ホームページ > php教程 > php手册 > PHP コア コードから require と include の違いを分析する

PHP コア コードから require と include の違いを分析する

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-13 12:12:33
オリジナル
1064 人が閲覧しました

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:
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/ zend_compile.c:4317:void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */

構造体 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 の違い: エラー情報の表示レベル (救済ありと救済なし)

if (type==ZEND_REQUIRE) { / When /require ;filename TSRMLS_CC);

}

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 の違いは、エラーが発生したときに、一方がエラーで、もう一方がエラーであることです。警告。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート