Deep understanding of PHP's Require/include order http://www.jb51.net/article/25867.htm
popularization
In the PHP manual:
Require () is identical to include () except upon failure it'll also produce a fatal level ERROR. In other words, it would halt the script whereas include () only emits a warning (e_warning) which allows the script to cont Inue.
This means that require will abort PHP when it fails, and include can continue to run.
What is the difference between the bottom? We bring this question together into the core code of PHP.
Here is a diagram of the PHP run process (where is this diagram from?) Brother Bird painted that? )
A tutorial: Lex is a code scanner, scanning code, YACC is yet Another Compiler Compiler, the role is to change the syntax of any one of the code into a YACC syntax, YACC is the parser (really TMD around).
Lex's suffix under C is *.l Yacc is *.y.
Business
Here is a record of the action:
cc@cc-laptop:/opt/workspace$ svn checkout Http://svn.php.net/repository/php/php-src/branches/PHP_5_3 php-src-5.3
Fetch the latest PHP source code from SVN.
Start deep:
cc@cc-laptop:/opt/workspace/php-src-5.3$ find. -type f-name "*.L"-exec grep-hn "require_once" {} \;
./zend/zend_language_scanner.l:1093: "Require_once" {
Look for the require_once in the Lex code scanner file, ZEND_LANGUAGE_SCANNER.L 1093 lines.
1093 "Require_once" {
1094 return t_require_once;
1095}
And then search the t_require_once,
cc@cc-laptop:/opt/workspace/php-src-5.3$ find. -type f-name "*.y"-exec grep-hn "T_include" {} \;
./zend/zend_language_parser.y:52:%left t_include t_include_once t_eval t_require T_REQUIRE_ONCE
./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);}
Near line 985, there is this group of code:
INTERNAL_FUNCTIONS_IN_YACC:
T_isset ' (' isset_variables ') ' {$$ = $;}
| T_empty ' (' variable ') ' {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);}
;
So, we need to continue to look deeper into zend_do_include_or_eval,
cc@cc-laptop:/opt/workspace/php-src-5.3$ find. -type f-name "*.c"-exec grep-hn "Zend_do_include_or_eval" {} \;
./zend/zend_compile.c:4317:void zend_do_include_or_eval (int type, Znode *result, const znode *OP1)/* {{* * *
A structure is assembled in the Zend_do_include_or_eval, Zend_include_or_eval.
and find Zend_vm_handler in the zend_vm_def.h (Zend_include_or_eval, const| tmp| var| CV, any):
Switch (Z_lval (opline->op2.u.constant)) {code slightly}
One of the key phrases in the middle is:
New_op_array = Compile_filename (Z_lval (opline->op2.u.constant), Inc_filename tsrmls_cc);
In the Zend_complie.h file:
Zend_api zend_op_array *compile_filename (int type, zval *filename tsrmls_dc);
This function is defined in the Zend_language_scaner.l file to find the core code:
if (open_file_for_scanning (File_handle tsrmls_cc) ==failure) {
Differences between require and include: level of display of error messages (with bailout and no bailout)
if (type==zend_require) {//require
Zend_message_dispatcher (Zmsg_failed_require_fopen, File_handle->filename tsrmls_cc);
Zend_bailout ();
} else {
Zend_message_dispatcher (Zmsg_failed_include_fopen, File_handle->filename tsrmls_cc);
}
compilation_successful=0;
} else {code slightly}
Continue tracking Zend_message_dispatcher can find the Php_message_handler_for_zend function in the main/main.c file:
Include output error message at the level: e_warning
Case Zmsg_failed_include_fopen:
Php_error_docref ("function.include" tsrmls_cc, E_warning, "Failed opening '%s ' for inclusion (include_path= '%s ')", php_ STRIP_URL_PASSWD ((char *) data), Str_print (PG (include_path)));
Break
Require output error message at the level: E_compile_error
Code slightly
The
Summary
is exactly consistent with the opening PHP manual, and the difference between require and include is that when errors occur, one is the error and the other is warning.