宝哥软件园

从php核心代码分析require和include的区别

编辑:宝哥软件园 来源:互联网 时间:2021-10-21

深刻理解php的require/include顺序//www . JB 51 . net/article/25867 . htm在PHP手册中普及:require()与include()相同。除非出现故障,否则还会产生致命的E_ERROR级错误。换句话说,当include()仅发出允许脚本继续的警告(e _ warning)时,它将停止脚本。也就是说,当它失败时,require将停止php运行,而include可以继续运行。有什么区别?让我们带着这个问题进入PHP的核心代码。下面是PHP运行过程的图(这个图是从哪里来的?鸟哥画的?)9500.163.com

补习一下:lex是代码扫描器,扫描代码用的,yacc是又一个编译器,作用是把任何一种代码的语法转成语法分析程序生成器语法,yacc就是解析器(真战区导弹防御绕)。法律在c下的后缀是*.l yacc是*.y正题下面看操作记录:[电子邮件保护]:/opt/workspace $ SVN查看http://svn.php.net/repository/php/php-src/branches/PHP_5_3 PHP-src-5.3从版本控制取最新的服务器端编程语言(专业超文本预处理器的缩写)源代码。开始深入:[电子邮件保护]:/opt/workspace/PHP-src-5.3 $ find .-键入f -name "* .l "-exec grep-Hn " require _ once " { } ;/Zend/Zend _ language _ scanner。l :1093:“require _ once”{ 0寻找法律代码扫描器文件中出现需要一次的地方,zend_language_scanner.l的1093行1093“REQUIRE _ ONCE”{ 1094返回T _ REQUIRE _ ONCE1095 }然后再搜一下T_REQUIRE_ONCE,[电子邮件保护]:/opt/workspace/PHP-src-5.3 $ find .-键入f -name "* .y "-exec grep-Hn " T _ INCLUDE " { } ;/Zend/Zend _ language _ parser。y :52:%左EVAL需要一次./Zend/Zend _ language _ parser。y :985: | T _ INCLUDE expr { Zend _ do _ INCLUDE _ or _ eval(Zend _ INCLUDE,$$,$ 2 TSRMLS _ CC);}./Zend/Zend _ language _ parser。y :986: | T _ INCLUDE _ ONCE expr { Zend _ do _ INCLUDE _ or _ eval(Zend _ INCLUDE _ ONCE,$$,$ 2 TSRMLS _ CC);}在985行附近,有这样一群代码:internal _ functions _ in _ yacc :t _ ISSET '(' ISSET _ variables ')' { $ $=$ 3;}| T_EMPTY '('变量)' { ZEND _ do _ isset _ or _ ISEMPTY(ZEND _ ISEMPTY,$$,$ 3 TSRMLS _ CC);} | T _ INCLUDE expr { ZEND _ do _ INCLUDE _ or _ eval(ZEND _ INCLUDE,$$,2美元TSRMLS _ CC);} | T _ INCLUDE _ ONCE expr { ZEND _ do _ INCLUDE _ or _ eval(ZEND _ INCLUDE _ ONCE,$$,$ 2 TSRMLS _ CC);} | T _ EVAL '(' expr ')' { ZEND _ do _ include _ or _ eval(ZEND _ EVAL,$$,3美元TSRMLS _ CC);} | T _ REQUIRE expr { ZEND _ do _ include _ or _ eval(ZEND _ REQUIRE,$$,2美元TSRMLS _ CC);} | T _ REQUIRE _ ONCE expr { ZEND _ do _ include _ or _ eval(ZEND _ REQUIRE _ ONCE,$$,$ 2 TSRMLS _ CC);};于是乎,我们需要继续深入寻找zend_do_include_or_eval,[电子邮件保护]:/opt/workspace/PHP-src-5.3 $ find .-键入f -name "* .c "-exec grep-Hn " Zend _ do _ include _ or _ eval " { } ;/Zend/Zend _ compile。c :4317: void Zend _ do _ include _ or _ eval(int类型,znode *result,const znode * op1 TSRMLS _ DC)/* { { */Zend _ do _ include _ or _ eval中组装了一个结构体,ZEND_INCLUDE_OR_EVAL。再在zend_vm_def.h中找到ZEND_VM_HANDLER(73,ZEND_INCLUDE_OR_EVAL,CONST|TMP|VAR|CV,ANY):开关(Z _ LVAL(op线-op2。u .常量)){ 0代码略}中间关键的一句是:new _ op _ array=compile _ filename(Z _ LVAL(op行-op 2。u . constant),Inc _ filename TSRMLS _ CC);在zend_complie.h文件中: ZEND _ API ZEND _ op _ array * compile _ filename(int类型,zval * filename TSRMLS _ DC);这个函数定义在zend_language_scaner.l文件中,找出最核心的代码:if(open _ file _ for _ scanning(file _ handle TSRMLS _ CC)==FAILURE){//require与包括的差别:错误信息的显示级别(有紧急援助和无救助)if(type==ZEND _ REQUIRE){//REQUIRE时Zend _ message _ dispatcher(ZMSG _ FAILED _ REQUIRE _ FOPEN,file _ handle-filename TSRMLS _ CC);Zend _ pailt();} else { Zend _ message _ dispatcher(ZMSG _ FAILED _ INCLUDE _ FOPEN,file _ handle-filename TSRMLS _ CC);}编译_成功=0;} else {代码略}继续追踪zend_message_dispatcher可以在主/主。c文件中找到php_message_handler_for_zend函数://包括输出错误信息时的级别为:E _ WARNING case ZMSG _ FAILED _ INCLUDE _ FoppHyphp _ error _ docref("函数。包括“警告”未能打开“%s”进行包含(include_path='%s ')”,PHP _ strip _ URL _ passwd((char *)数据),STR _ PRINT(PG(INCLUDE _ path));打破;//需要输出错误信息时的级别为:E_COMPILE_ERROR代码略总结和开头服务器端编程语言(专业超文本预处理器的缩写)手册所说完全一致,要求和包括的区别在于,出现错误时,一个是错误一个是警告。

更多资讯
游戏推荐
更多+