Analyze the difference between require and include from the php core code

Source: Internet
Author: User
I can't help but go deep into the requireinclude sequence of PHP when I see the article of laruence. here I will record the in-depth process for future reference. A deep understanding of PHP's require/include sequential http://www.jb51.net/article/25867.htm
Popularity
In the php manual:

Require () is identical to include () failed T upon failure it will also produce a fatal E_ERROR level error. in other words, it will halt the script whereas include () only emits a warning (E_WARNING) which allows the script to continue.

In other words, when a failure occurs, require suspends the php operation, while include can continue to run.
What are the differences? Let's bring this question to the core code of PHP.
The following figure shows the PHP running process (where does this figure come from? Painted by laruence ?)

Tutorial: lex is a code scanner and used for scanning code. yacc is Yet Another Compiler, which converts the syntax of any code into yacc, yacc is the parser (really TMD around ).
The suffix of lex in c is *. l yacc is *. y

Question
The operation records are as follows:

Cc @ cc-laptop:/opt/workspace $ svn checkout http://svn.php.net/repository/php/php-src/branches/PHP_5_3 php-src-5.3
Obtain the latest php source code from svn.

Start in-depth:

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 "{
Find the location where require_once appears in the lex code scanner file, line 1093 of zend_language_scanner.l.
1093 "require_once "{
1094 return T_REQUIRE_ONCE;
1095}

Search for T_REQUIRE_ONCE,

Cc @ cc-laptop:/opt/workspace/php-src-5.3 $ find.-type f-name "*. y"-exec grep-Hn "T_INCLUDE "{}\;
./Zend/zend_incluage_parser.y: 52: % left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
./Zend/zend_incluage_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 );}

There is such a group of code near Row 3:

Internal_functions_in_yacc:
T_ISSET '('isset_variables') '{$ $ = $3 ;}
| 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 );}
;

Therefore, we need to continue looking for 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 TSRMLS_DC )/*{{{*/

Zend_do_include_or_eval assembles a struct, ZEND_INCLUDE_OR_EVAL.

Find ZEND_VM_HANDLER (73, ZEND_INCLUDE_OR_EVAL, CONST | TMP | VAR | CV, ANY) in zend_vm_def.h ):
Switch (Z_LVAL (opline-> op2.u. constant) {code omitted}

The key sentence 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 ){
// Difference between require and include: Display level of error messages (including sorted lout and non-sorted lout)
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 omitted}

To continue tracing zend_message_dispatcher, you can find the php_message_handler_for_zend function in the main/main. c file:

// Include: E_WARNING
Case ZMSG_FAILED_INCLUDE_FOPEN:
Php_error_docref ("function. include "TSRMLS_CC, E_WARNING," Failed opening '% s' for future Sion (include_path =' % s') ", php_strip_url_passwd (char *) data ), STR_PRINT (PG (include_path )));
Break;
// When require outputs an error message, the level is E_COMPILE_ERROR.
Code omitted

Summary
The difference between require and include is that when an error occurs, one is error and the other is warning.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.