从php核心代码分析require和include的区别_php技巧
深入理解PHP之require/include顺序 http://www.jb51.net/article/25867.htm
普及
在php手册中:
require() is identical to include() except 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.
就是说在失败的时候,require是会中止php运行的,而include是可以继续运行的。
倒底有什么样的区别呢?我们带着这个疑问来一起进入PHP的核心代码。
下面是一个PHP运行过程的图(这个图是出自哪里的?鸟哥画的?)
补习一下:lex是代码扫描器,扫描代码用的,yacc是Yet Another Compiler Compiler,作用是把任何一种代码的语法转成yacc语法,yacc就是解析器(真TMD绕)。
lex在c下的后缀是*.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代码扫描器文件中出现require_once的地方,zend_language_scanner.l的1093行。
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/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 ‘(‘ 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); }
;
于是乎,我们需要继续深入寻找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中组装了一个结构体,ZEND_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的差别:错误信息的显示级别(有bailout和无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 {代码略}
继续追踪zend_message_dispatcher可以在main/main.c文件中找到php_message_handler_for_zend函数:
//include输出错误信息时的级别为: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输出错误信息时的级别为:E_COMPILE_ERROR
代码略
总结
和开头PHP手册所说完全一致,require和include的区别在于,出现错误时,一个是error一个是warning。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











vue3+vite:src는 require를 사용하여 이미지를 동적으로 가져오고 vue3+vite는 여러 이미지를 동적으로 가져옵니다. vue3을 사용하는 경우 require는 이미지를 사용할 수 없습니다. imgUrl:require(' .../assets/test.png') 와 같은 vue2는 typescript가 require를 지원하지 않기 때문에 가져오므로 이를 해결하는 방법은 다음과 같습니다. waitimport를 사용합니다.

PHP를 사용하여 웹 페이지를 작성할 때 때로는 현재 PHP 파일에 다른 PHP 파일의 코드를 포함해야 할 때가 있습니다. 이때, include 또는 include_once 함수를 사용하여 파일 포함을 구현할 수 있습니다. 그렇다면 include와 include_once의 차이점은 무엇입니까?

require 사용법: 1. 모듈 소개: 많은 프로그래밍 언어에서 require는 외부 모듈이나 라이브러리를 소개하여 이들이 제공하는 기능을 프로그램에서 사용할 수 있도록 하는 데 사용됩니다. 예를 들어 Ruby에서는 require를 사용하여 타사 라이브러리나 모듈을 로드할 수 있습니다. 2. 클래스 또는 메서드 가져오기: 일부 프로그래밍 언어에서는 require를 사용하여 특정 클래스나 메서드를 현재 파일에서 사용할 수 있도록 가져옵니다. 3. 특정 작업 수행: 일부 프로그래밍 언어나 프레임워크에서는 특정 작업이나 기능을 수행하는 데 require가 사용됩니다.

PHP 헤더의 fatalerror:require():Failedopeningrequired'data/tdk.php'(include_path='.;C:phppear') 해결 단계 PHP를 사용하여 웹사이트나 애플리케이션을 개발할 때 다양한 오류가 자주 발생합니다. 일반적인 오류 중 하나는 "fatalerror:require():Failed"입니다.

PHP에서 require 키워드의 역할과 사용법에 대한 자세한 설명 PHP 개발에서 require는 매우 일반적으로 사용되는 키워드입니다. 그 기능은 현재 스크립트에서 사용하기 위해 지정된 파일을 포함하는 것입니다. 이번 글에서는 require 키워드의 기능과 사용법을 자세히 설명하겠습니다. 1. require 키워드의 역할 require 키워드는 현재 스크립트에 파일의 내용을 포함시킬 수 있습니다. 일반적으로 라이브러리 파일, 구성 파일 등과 같은 필요한 외부 파일을 포함하는 데 사용됩니다. 요구사항 사용

PHP 헤더의 FatalError:require():Failedopeningrequired'data/tdk.php'를 해결하는 단계 PHP 웹사이트를 개발하고 유지 관리할 때 다양한 오류와 예외가 자주 발생합니다. 일반적인 오류 중 하나는 "FatalError:require():Failedopeningrequired'data/tdk.php'"입니다.

소개 PHP에서는 해당 내장 래퍼의 도움으로 다양한 URL 스타일 프로토콜을 파일 시스템 기능과 함께 사용할 수 있습니다. stream_wrapper_register() 함수를 사용하여 사용자 정의 래퍼를 정의할 수도 있습니다. PHP의 기본 래퍼는 로컬 파일 시스템을 나타내는 file://입니다. 다른 프로토콜이 명시적으로 사용되지 않으면 PHP 파서는 이를 파일 시스템 래퍼로 처리합니다. 파일 시스템 함수 fopen(), file_get_contents() 등에 전달된 파일 이름 매개변수는 기본적으로 file:// 프로토콜을 사용합니다. 파일 이름이 슬래시, 백슬래시 또는 Windows 드라이버로 시작하지 않는 경우

기본 php,ini 파일에 .ini 파일을 포함할 수 없습니다. 대조적으로, PHP를 컴파일할 때 --with-config-file-scan-dir=PATH&a 줄은
