PHP マニュアルの PHP の require/include シーケンス http://www.jb51.net/article/25867.htm
Popular
についての深い理解:
require() は、失敗時に致命的な E_ERROR レベルのエラーを生成する点を除いて、include() と同じです。つまり、include() はスクリプトを許可する警告 (E_WARNING) を発行するだけです。続けてください。
つまり、失敗すると、require は php の実行を停止しますが、include は実行を継続できます。
違いは何ですか?この質問では PHP のコアコードを入力してみましょう。
以下は、PHP の実行プロセスの画像です (この画像はどこから来たのですか? Brother Bird が描いたのでしょうか?)
簡単なおさらい: lex はコードのスキャンに使用されるコード スキャナー、yacc は Yet Another Compiler コンパイラー、その機能はあらゆるコードの構文を yacc 構文に変換すること、そして yacc はパーサー (本当にめちゃくちゃです) です。
c の lex のサフィックスは *.l で、yacc は *.y です
メイントピック
以下の操作記録を参照してください:
cc@cc-laptop:/opt/workspace$ svn checkout http://svn.php.net/repository/php/php-src/branches/PHP_5_3 php-src-5.3
svn から最新情報を入手phpのソースコード。
さらに深く進み始めます:
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” {
lex コード スキャナー ファイル、zend_ language_scanner.l の 1093 行目で、require_once が出現する場所を探します。
1093 “require_once” {
1094 return T_REQUIRE_ONCE;
1095 }
次に、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_ language_parser.y:986: | T_INCLUDE_ONCE expr { zend_do_include_or_eval(ZEND_INCLUDE_ONCE, &$$, &$2 TSRMLS_CC) }
行 985 の近くに、次のようなコードのグループがあります:
internal_functions_in_yacc:
./Zend/ zend_compile.c:4317:void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
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) ' { zend_do_include_or_eval(ZEND_EVAL, &$$, &$3 TSRMLS_CC); RE expr { zend_do_include_or_eval(ZEND_REQUIRE, &$$, &$2 TSRMLS_CC) }
| or_eval(ZEND_REQUIRE_ONCE , &$$, &$2 TSRMLS_CC);
したがって、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_INCLUDE_OR_EVAL は zend_do_include_or_eval でアセンブルされます。
中央の重要な文は次のとおりです:zend_vm_def.h で ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) を見つけます:
switch (Z_LVAL(opline->op2.u.constant)) {コード省略}
new_op_array =compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
zend_complie.h ファイル内:
ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC);
この関数は zend_ language_scaner.l ファイルで定義されています:
のコア コードを見つけます。
if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {
// require と include の違い: エラー情報の表示レベル (救済ありと救済なし)
}
compilation_success=0;} else {コード省略}コードが省略されています
引き続き zend_message_dispatcher を追跡すると、main/main.c ファイルに php_message_handler_for_zend 関数が見つかります。
//インクルードがエラー情報を出力するときのレベルは次のとおりです: E_WARNING
case ZMSG_FAILED_INCLUDE_FOPEN:
php_error_docref(“function.include” TSRMLS_CC, E_WARNING, “インクルードのために '%s' を開くことができませんでした (include_path='%s) ')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));
break;
//require エラー情報を出力する際のレベルは、E_COMPILE_ERROR
まとめ
最初にPHPのマニュアルで述べたことと全く同じです。 require と include の違いは、エラーが発生したときに、一方がエラーで、もう一方がエラーであることです。警告。