Welcome to the website navigation,本站只接受合法正规的企业网站,欢迎站长们提交你的网站获得展示和流量有任何问题请联系站长,欢迎大家加入本站。

                
提交网站
  • 网站:76083
  • 待审:5
  • APP:577
  • 文章:304411
  • 会员:56004
文字内链包年1000元 文字内链包年1000元 文字内链包年1000元 AI办公网站 AI绘画工具 AIchat

名站导航为爱好php程序的朋友们提供php相关的教程知识。

在PhP程序中,用户函数的定义从function关键字开始。如下所示简单示例:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

function foo($var) {
    echo $var;
}

这是一个非常简单的函数,它所实现的功能是定义一个函数,函数有一个参数,函数的内容是在标准输出端输出传递给它的参数变量的值。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

函数的一切从function开始。我们从function开始函数定义的探索之旅。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

词法分析

在 Zend/zend_language_scanner.l中我们找到如下所示的代码:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

"function" {
    return T_FUNCTION;
}

它所表示的含义是function将会生成T_FUNCTION标记。在获取这个标记后,我们开始语法分析。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

语法分析

在 Zend/zend_language_parser.y文件中找到函数的声明过程标记如下:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

function:
    T_FUNCTION { $$.u.opline_num = CG(zend_lineno); }
;
 
is_reference:
        /* empty */ { $$.op_type = ZEND_RETURN_VAL; }
    |   '&'         { $$.op_type = ZEND_RETURN_REF; }
;
 
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); }
;

关注点在 function is_reference T_STRING,表示function关键字,是否引用,函数名。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

T_FUNCTION标记只是用来定位函数的声明,表示这是一个函数,而更多的工作是与这个函数相关的东西,包括参数,返回值等。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

生成中间代码

语法解析后,我们看到所执行编译函数为zend_do_begin_function_declaration。在 Zend/zend_complie.c文件中找到其实现如下:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

void zend_do_begin_function_declaration(znode *function_token, znode *function_name,
 int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */
{
    ...//省略
    function_token->u.op_array = CG(active_op_array);
    lcname = zend_str_tolower_dup(name, name_len);
 
    orig_interactive = CG(interactive);
    CG(interactive) = 0;
    init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
    CG(interactive) = orig_interactive;
 
     ...//省略
 
    if (is_method) {
        ...//省略 类方法 在后面的类章节介绍 www.mzdh.net
    } else {
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
 
        opline->opcode = ZEND_DECLARE_FUNCTION;
        opline->op1.op_type = IS_CONST;
        build_runtime_defined_function_key(&opline->op1.u.constant, lcname,
            name_len TSRMLS_CC);
        opline->op2.op_type = IS_CONST;
        opline->op2.u.constant.type = IS_STRING;
        opline->op2.u.constant.value.str.val = lcname;
        opline->op2.u.constant.value.str.len = name_len;
        Z_SET_REFCOUNT(opline->op2.u.constant, 1);
        opline->extended_value = ZEND_DECLARE_FUNCTION;
        zend_hash_update(CG(function_table), opline->op1.u.constant.value.str.val,
            opline->op1.u.constant.value.str.len, &op_array, sizeof(zend_op_array),
             (void **) &CG(active_op_array));
    }
 
}
/* }}} */

生成的中间代码为 ZEND_DECLARE_FUNCTION ,根据这个中间代码及操作数对应的op_type。 我们可以找到中间代码的执行函数为 ZEND_DECLARE_FUNCTION_SPEC_hANDLER。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

在生成中间代码时,可以看到已经统一了函数名全部为小写,表示函数的名称不是区分大小写的。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

为验证这个实现,我们看一段代码:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

function T() {
    echo 1;
}
 
function t() {
    echo 2;
}

执行代码,可以看到屏幕上输出如下报错信息:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

Fatal error: Cannot redeclare t() (previously declared in ...)

表示对于PhP程序来说T和t是同一个函数名。检验函数名是否重复,这个过程是在哪进行的呢? 下面将要介绍的函数声明中间代码的执行过程包含了这个检查过程。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

执行中间代码

在 Zend/zend_vm_execute.h 文件中找到 ZEND_DECLARE_FUNCTION中间代码对应的执行函数:ZEND_DECLARE_FUNCTION_SPEC_hANDLER。 此函数只调用了函数do_bind_function。其调用代码为:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

do_bind_function(EX(opline), EG(function_table), 0);

在这个函数中将EX(opline)所指向的函数添加到EG(function_table)中,并判断是否已经存在相同名字的函数,如果存在则报错。 EG(function_table)用来存放执行过程中全部的函数信息,相当于函数的注册表。 它的结构是一个hashTable,所以在do_bind_function函数中添加新的函数使用的是hashTable的操作函数zend_hash_add。Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!


Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

名站网址导航

PhP程序内核探索:函数的参数Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

我们对于参数的类型提示做了分析,这里我们在这一小节的基础上,进行一些更详细的说明。 在经过词语分析,语法分析后,我们知道对于函数的参数检查是通过 zend_do_receive_arg 函数来实现的。在此函数中对于参数的关键代码如下:Ra4AIChat_企业网址导航_网址分类目录_企业黄页网址提交查询专业网站!

好了关于php程序的知识就说到这里希望可以帮助需要的朋友。,

标签:

分享到:

  admin

注册时间:

网站:0 个   APP:3 个  文章:0 篇

  • 76083

    网站

  • 577

    APP

  • 304411

    文章

  • 56004

    会员

赶快注册账号,推广您的网站吧!
文章分类
热门网站
最新入驻APP小程序

宝贝市场2023-02-08

宝贝市场——买手和卖家商品展示

夺宝助手2023-02-08

夺宝助手小程序,查看每日快夺宝平

查诚信2023-02-08

查诚信是一款免费的商业查询工具

车价天天报2023-02-08

快速连接汽车销售,获知汽车最新报

考勤助理小程序2023-02-08

上班签到考勤,实时定位,后台轻松

汽车报价大全查询2023-02-08

汽车报价大全查询提供最新汽车市