转自 http://www.guangla.com/post/2014-01-24/40060857811

起因:

一朋友面试被问到,php的include和require的区别,这个可能是面试中出现机率比较高的问题。网上众说纷云,他说他也搞晕了。

手册上的说明:

require 和 include  几乎完全一样,除了处理失败的方式不同之外。require  在出错时产生 E_COMPILE_ERROR  级别的错误。换句话说将导致脚本中止而 include  只产生警告(E_WARNING),脚本会继续运行。

从手册上明确知道他们之间的唯一区别就是,require出错会中止脚本,那为什么网上还有各种版本的区别,所以必需从源码上来终结。

源码追踪:

要进行源码追踪,先了解下php的大概的运行原理:php代码 ->代码扫描 ->代码翻译 -> zend vm执行 -> 输出

1、找到 require 在代码扫描文件在地址(Zend/zend_language_scanner.l)中 1262 - 1264行:

<ST_IN_SCRIPTING>"require" {
                  return T_REQUIRE;
              }

2、继续找T_REQUIRE, 在 (Zend/zend_language_parser.y)中的 1259行

T_REQUIRE expr            { zend_do_include_or_eval(ZEND_REQUIRE, &$$, &$2 TSRMLS_CC); }

发现 zend_do_include_or_eval 这个函数

3、 继续找 zend_do_include_or_eval, 在 (Zend/zend_compile.c)中的 6186行:

opline->opcode = ZEND_INCLUDE_OR_EVAL;

发现把opcode设置为 ZEND_INCLUDE_OR_EVAL,

4、继续找ZEND_INCLUDE_OR_EVAL的定义,在 (Zend/zend_vm_def.h)中的 3935行开始,发现目标在4002-4005,(3963-4001是include_once require_once的判断,发现这两也走的同一套逻辑,这里段代码里也可以明显看出 _once的处理逻辑)

case ZEND_INCLUDE:
              case ZEND_REQUIRE:
                       new_op_array = compile_filename(opline->extended_value, inc_filename TSRMLS_CC);
              break;

5、继续找compile_filename,定义在(Zend/zend_language_scanner.c)中的 612行中:

retval = zend_compile_file(&file_handle, type TSRMLS_CC);

6、继续找zend_compile_file, 在zend.c 689行:

zend_compile_file = compile_file;

7、 继续找zend api定义的compile_file方法,在(Zend/zend_language_scanner.l)中553行找到这个方法定义:

if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {
                    if (type==ZEND_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;
              }

在这里终于发现  include和require的区别了,明显可以看出没有找到文件的话,require,会执行zend_bailout(); ,继续看zend_bailout();会发现,最终会退出脚本执行。

结论:

在1~6 步中 ,include和require始终走的是同一逻辑,只有在第7步才有区别判断,从代码中可以得出结论和手册中一致。希望这篇文章能够给这个命题下一个最终结论。

php include 与 require 起底[转]的更多相关文章

  1. include、require、include_once和require_once理解

    都是在当前文件中包含引入并运行指定文件,include和require的不通之处仅仅在于发生错误时include产生一个警告脚本继续执行,而require产生一个致命的错误,脚本停止运行.有了once ...

  2. include与require的区别?

    require()语句的性能与include()相类似,都是包括并运行指定文件.不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估:而对于require()来说,文件只处理 ...

  3. PHP中include()与require()

    引用文件的方法有两种:require 及 include. require 的使用方法如 require("file.php"); .这个函数通常放在 PHP 程序的最前面,PHP ...

  4. php中include()和require()的区别

    1.引用文件方式 对 include()来说,在include()执行时文件每次都要进行读取和评估:而对于require()来说,文件只处理一次(实际上,文件内容替换 了require()语句.这就意 ...

  5. PHP入门二【PHP include 和 require的区别】

    include (或 require)语句会获取指定文件中存在的所有文本/代码/标记,并复制到使用 include 语句的文件中.包含文件很有用,如果您需要在网站的多张页面上引用相同的 PHP.HTM ...

  6. PHP中include和require的区别详解

    1.概要 require()语句的性能与include()相类似,都是包括并运行指定文件.不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估:而对于require()来说, ...

  7. PHP include 和 require 语句

    在 PHP 中,您可以在服务器执行 PHP 文件之前在该文件中插入一个文件的内容. include 和 require 语句用于在执行流中插入写在其他文件中的有用的代码. include 和 requ ...

  8. 包含文件函数include与require的区别

    include或include_once一般用于动态包含,所谓动态包含就是根据不同条件包含不同文件 require或require_once一般用于静态包含,比如包含一个html文件的头部或者尾部 如 ...

  9. PHP中include和require(转)

    昨天去面试一个php开发,看到笔试试卷上有这么一道题目: include和require有什么区别? 这个题目可以称得上php开发面试中的必考题目,网上也有各种答案和解释.但是我当时却真的想不起来了. ...

随机推荐

  1. asp.net mvc4 webapi Post 参数 字符串

    用  mvc4中的WEBAPI, Post 到后台的参数如果为string,则直接接收不到,解决方案有两种 1.传递参数为自定义类 2.通过如下方式获取: //获取传统context var cont ...

  2. 自动文档摘要评价方法:Edmundson,ROUGE

    自动文档摘要评价方法大致分为两类: (1)内部评价方法(Intrinsic Methods):提供参考摘要,以参考摘要为基准评价系统摘要的质量.系统摘要与参考摘要越吻合, 质量越高. (2)外部评价方 ...

  3. Problem A: The Monocycle

    uva10047:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&am ...

  4. Spring: DispacherServlet和ContextLoaderListener中的WebApplicationContext的关系

    在Web容器(比如Tomcat)中配置Spring时,你可能已经司空见惯于web.xml文件中的以下配置代码: <context-param> <param-name>cont ...

  5. dns智能解析对网站排名的影响

    网站排名是所有建站者都关系的问题,如何提升网站排名有很多因素,网站是否健康也与网站排名有关,下面智儒科技网站建设为你研究下如何判断自己的网站是否健康. 一般情况下,网站的排名在优化的基础上,怎么也上不 ...

  6. BZOJ 1048 [HAOI2007]分割矩阵

    1048: [HAOI2007]分割矩阵 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 623  Solved: 449[Submit][Status ...

  7. 2015 BJOI 0102 Secret

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=477 试题描述: 在 MagicLand 这片神奇的大陆上,有样一个古老传说 ...

  8. codeforce-191E-Thwarting Demonstrations(树状数组+二分+离散)

    题意: 求第K 大连续区间 分析: 二分答案,再n * log(n)判断有几个区间的区间和大于mid,然后调整上下界,使这个值不断的接近k. 判断符合条件的区间总数:线性扫描sum[n](前n项和) ...

  9. HDU 5416 CRB and Tree

    题目大意: T, T组测试数据 给你一个n有n个点,下标是从 1 开始的.这个是一棵树,然后下面是n-1条边, 每条边的信息是 s,e,w 代表 s-e的权值是w 然后是一个Q代表Q次询问. 每次询问 ...

  10. 动态规划(斜率优化):[CEOI2004]锯木厂选址

    锯木场选址(CEOI2004) 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能按照一个方向运输:朝山下运.山脚下有 ...