PHP源代码简单分析

PHP源代码简单分析

1. 目录结构

   1. build 和编译有关的目录。

   2. ext 扩展库代码,例如 Mysqlzlibiconv 等我们熟悉的扩展库。

   3. main 主目录。

   4. sapi 和各种服务器的接口调用,例如apacheIIS等,也包含一般的fastcgicgi等。

   5. win32 Windows 下编译 PHP 有关的脚本。用了 WSH

   6. Zend 文件夹核心的引擎。

2. PHP使用LexYacc对语法进行解析。

   Zend 目录下有两个文件 zend_language_parser.y zend_language_scanner.l 他们是LexYacc的脚本文件,通过这两个脚本文件生成对应的.c.h文件,实际上这在 linux 下非常普遍,gcc 也使用它们产生语树。

3. PHP如何使用Mysql

   ext 目录下有一个 mysql 子目录,这个目录中的php_mysql.c php_mysql.h 负责 PHP Mysql 操作。使用了 Mysql 手册中的 C 语言 API

4. 安全模式?

   main 文件夹下的safe_mode.h safe_mode.c 文件负责PHP的安全模式。

5. 那些是 PHP 的标准函数,那些是扩展函数?

   ext 目录下英文意思是扩展,而在 ext 下还是有一个 standard 文件夹,存放着 PHP 中的标准函数,例如 explode 这个函数是在 ./ext/standard/string.c 下定义的。

6. PHP 源代码中的PHP_FUNCTION(xx) 宏。

   这个宏用来检验一个函数名称是否合法。合法的函数名称应该由小写字母及下划线组成。

7. 那些函数集是标准的?

   通过 ./ext/standard/ 目录我们可以看到以下常用函数集是标准的。字符串函数集、数组函数集、文件及目录操作函数集、md5算法等。

8. 一些函数的实现过程

   1. fsockopen, pfsockopen 的实现

      这两个函数的实现离不开 ./ext/standard/fsock.c 文件中的 php_fsockopen_stream 函数。具体的socket都在./main/network.c 中实现。

9. PHP 函数集注册过程

   ./main/internal_functions.c 中有一个数组 php_builtin_extensions 默认下有以下成员:

  

   1. phpext_bcmath_ptr

   2. phpext_calendar_ptr

   3. phpext_com_dotnet_ptr

   4. phpext_ctype_ptr

   5. phpext_date_ptr

   6. phpext_ftp_ptr

   7. phpext_hash_ptr

   8. phpext_odbc_ptr

   9. phpext_pcre_ptr

   10. phpext_reflection_ptr

   11. phpext_session_ptr

   12. phpext_spl_ptr

   13. phpext_standard_ptr

   14. phpext_tokenizer_ptr

   15. phpext_zlib_ptr

  

   接着 php_register_extensions(php_builtin_extensions, EXTCOUNT TSRMLS_CC) 进行注册

  

10. 有趣的Zend LOGO图片

       ./main/logos.h 文件中,用 zend_logo php_logo 数组保存了 PHP 标志和 Zend 标志。所以你根本在发行包里找不到zend.gif

11. PHP的语法树?

  

    1. LexYacc

       市面上有这本书。大家可以买来看看,包括GCC都是用它们兄弟生成的语法树。如果对编译器感兴趣。可以翻阅市面上关于这方面的书,并不多就几本。

   

    2. .l.y语法树文件

       ./Zend/zend_language_scanner.l./Zend/zend_language_parser.y 规定了PHP的语法。从字面意义上scanner表示语法初步扫描,parser表示语法解析。根据这两个文件lexyacc可以生成对应的c代码。所以相对来说生成语法是很方便的。

  

    3. 如何定义一个符号

       例如 if($language='php') 这一句中的if 就是一个token 语法中我们用T_IF表示。具体在.l文件中如下定义了:

      

 

       < ST_IN_SCRIPTING > " if " {

               return T_IF;

       }

 

      这样.php文件中的if就会被翻译成内置符号T_IF。’(单引号)被如下定义:

 

       < ST_SINGLE_QUOTE > [ ' ] {

             BEGIN(ST_IN_SCRIPTING);

             return ' / '' ;

       }

 

      

   4. 复合符号例如最常见的变量命名$discuz_user, $submit 等。

 

       < ST_IN_SCRIPTING , ST_DOUBLE_QUOTES , ST_HEREDOC , ST_BACKQUOTE > " $ " {LABEL} {

             zend_copy_value(zendlval , (yytext + 1 ) , (yyleng - 1 ));

             zendlval -> type = IS_STRING ;

             return T_VARIABLE;

       }

 

  

   5. 一个有效的if语句过程

      这个定义在zend_language_parser.y 189:

 

       T_IF ' ( ' expr ' ) ' {

             zend_do_if_cond( & $ 3 , & $ 4 TSRMLS_CC);

       } statement {

             zend_do_if_after_statement( & $ 4 , 1 TSRMLS_CC);

       } elseif_list else_single {

             zend_do_if_end(TSRMLS_C);

       }

       | T_IF ' ( ' expr ' ) ' ' : ' {

             zend_do_if_cond( & $ 3 , & $ 4 TSRMLS_CC);

       } inner_statement_list {

             zend_do_if_after_statement( & $ 4 , 1 TSRMLS_CC);

       } new_elseif_list new_else_single T_ENDIF ' ; ' {

             zend_do_if_end(TSRMLS_C);

       }

 

      if 后面必须存在(),圆括弧里面是表达式 expr 表达式在734行被定义:

 

       expr:

             r_variable { $$ = $ 1 ; }

             | expr_without_variable { $$ = $ 1 ; }

       ;

 

      if 后面可以跟 elseif 语句及 else 语句。

      从语法树里面我们看出 if () 后面是可以跟 : 的,这一般很少被使用吧。

 

   6. 优先级和左右结合性

      一般情况下.y文件中最先定义的操作符优先级相对低,并且可以使用%left%right 进行描述左右结合性,例如:

 

       % left ' + ' ' - ' ' . '

       % left ' * ' ' / ' ' % '

       % right ' ! '

 

      这说明'!' PHP 语法中是右结合的, '*' '/' '%' '+' '-' '.' 是左结合的,并且'!'的优先级更高

      例如语法 !$a + $b 要先计算 !$a 在进行加法操作

      %left ',' 被放在最上面定义,说明他的优先级最低,因为我们知道','可以等同一个语句。

 

   7. php.ini的解析

 

      1. 如果规定数值正负?

 

         < INITIAL > [ ] * ( " true " | " on " | " yes " )[ ] *    {

               ini_lval -> value . str . val   =    zend_strndup( " 1 " ,     1 );

               ini_lval -> value . str . len   =     1 ;

               ini_lval -> type   =     IS_STRING ;

                return    CFG_TRUE;

       }

 

        < INITIAL > [ ] * ( " false " | " off " | " no " | " none " )[ ] *    {

               ini_lval -> value . str . val   =    zend_strndup( "" ,     0 );

               ini_lval -> value . str . len   =     0 ;

               ini_lval -> type   =     IS_STRING ;

                return    CFG_FALSE;

       }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值