设为首页 收藏本站
查看: 681|回复: 0

[经验分享] 原:PHP内核研究 函数的参数

[复制链接]

尚未签到

发表于 2017-4-4 10:54:26 | 显示全部楼层 |阅读模式






在上一节中,分析了函数的定义,

函数的定义只是将函数名注册到函数列表的过程.

下面继续分析函数的参数.

如果没有看就移步到>>原:PHP内核研究
函数的定义,

,

function $test($arg=11){

}

还是要看Lex的语法分析


[c]
unticked_function_declaration_statement:
                function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); }
                        '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
[/c]



parameter_list 就是分析参数的地方

经过分析找到了解析参数的函数

zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$1, &$2, 0 TSRMLS_CC);

这里先要说一下 用来保存函数的结构体zend_arg_info


[c]
typedef struct _zend_arg_info {
        const char *name;        //参数名
        zend_uint name_len;      //参数名长度
        const char *class_name;  //参数为类时,指定类名
        zend_uint class_name_len;//类名长度
        zend_bool array_type_hint;//参数是否是数组
        zend_bool allow_null;      //参数是否允许为空
        zend_bool pass_by_reference; //参数是否为引用 也就是有没有使用&
        zend_bool return_reference;  //函数自身是否是一个引用函数
        int required_num_args;      //最少传递几个参数
} zend_arg_info;
[/c]




zend_do_receive_arg定义在Zend/zend_compile.c中


[c]
void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, const znode *initialization, znode *class_type, const znode *varname, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */
{
        zend_op *opline;
        zend_arg_info *cur_arg_info;//声明一个函数结构指针
        if (class_type->op_type == IS_CONST && //这里是类相关处理 暂时跳过 讲到类的时候再细说
            跳过....
        }

        if (var->op_type == IS_CV &&
            var->u.var == CG(active_op_array)->this_var &&
            (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) {
                zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
        } else if (var->op_type == IS_VAR &&
            CG(active_op_array)->scope &&
                ((CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) &&
                (Z_TYPE(varname->u.constant) == IS_STRING) &&
                (Z_STRLEN(varname->u.constant) == sizeof("this")-1) &&
                (memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")) == 0)) {
                zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
        }
        //创建一个op
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
        CG(active_op_array)->num_args++;//参数的个数
        opline->opcode = op;  //中间码 ZEND_RECV
        opline->result = *var;//返回值
        opline->op1 = *offset;
        if (op == ZEND_RECV_INIT) {
                opline->op2 = *initialization;
        } else {
                CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
                SET_UNUSED(opline->op2);
        }
        //复制参数列表到arr_info
        CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
        cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
        cur_arg_info->name_len = varname->u.constant.value.str.len;
        cur_arg_info->array_type_hint = 0;
        cur_arg_info->allow_null = 1;
        cur_arg_info->pass_by_reference = pass_by_reference;
        cur_arg_info->class_name = NULL;
        cur_arg_info->class_name_len = 0;
        //这个时候 cur_arg_info->name的值就是 $arg;也就是我们传递过来的参数名
        if (class_type->op_type != IS_UNUSED) {//跳过
               有略过....
        }
        opline->result.u.EA.type |= EXT_TYPE_UNUSED;
}
[/c]

如果函数有N个参数,那么 此函数就会执行N次

下一节将继续介绍 函数的返回值

原文出处:
原:PHP内核研究
函数的参数

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-359983-1-1.html 上篇帖子: php中使用Content-type类别列表 下篇帖子: php 导出word格式的数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表