php include 与 require 起底[转]
转自 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 起底[转]的更多相关文章
- include、require、include_once和require_once理解
都是在当前文件中包含引入并运行指定文件,include和require的不通之处仅仅在于发生错误时include产生一个警告脚本继续执行,而require产生一个致命的错误,脚本停止运行.有了once ...
- include与require的区别?
require()语句的性能与include()相类似,都是包括并运行指定文件.不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估:而对于require()来说,文件只处理 ...
- PHP中include()与require()
引用文件的方法有两种:require 及 include. require 的使用方法如 require("file.php"); .这个函数通常放在 PHP 程序的最前面,PHP ...
- php中include()和require()的区别
1.引用文件方式 对 include()来说,在include()执行时文件每次都要进行读取和评估:而对于require()来说,文件只处理一次(实际上,文件内容替换 了require()语句.这就意 ...
- PHP入门二【PHP include 和 require的区别】
include (或 require)语句会获取指定文件中存在的所有文本/代码/标记,并复制到使用 include 语句的文件中.包含文件很有用,如果您需要在网站的多张页面上引用相同的 PHP.HTM ...
- PHP中include和require的区别详解
1.概要 require()语句的性能与include()相类似,都是包括并运行指定文件.不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估:而对于require()来说, ...
- PHP include 和 require 语句
在 PHP 中,您可以在服务器执行 PHP 文件之前在该文件中插入一个文件的内容. include 和 require 语句用于在执行流中插入写在其他文件中的有用的代码. include 和 requ ...
- 包含文件函数include与require的区别
include或include_once一般用于动态包含,所谓动态包含就是根据不同条件包含不同文件 require或require_once一般用于静态包含,比如包含一个html文件的头部或者尾部 如 ...
- PHP中include和require(转)
昨天去面试一个php开发,看到笔试试卷上有这么一道题目: include和require有什么区别? 这个题目可以称得上php开发面试中的必考题目,网上也有各种答案和解释.但是我当时却真的想不起来了. ...
随机推荐
- 使用jQuery动态加载js脚本文件的方法
动态加载Javascript是一项非常强大且有用的技术.这方面的主题在网上已经讨论了不少,我也经常会在一些个人项目上使用RequireJS和Dojo加载js 它们很强大,但有时候也会得不偿失.如果你使 ...
- 03:计算(a+b)/c的值
总时间限制: 1000ms 内存限制: 65536kB 描述 给定3个整数a.b.c,计算表达式(a+b)/c的值,/是整除运算. 输入 输入仅一行,包括三个整数a.b.c, 数与数之间以一个空格 ...
- c#xml序列化对象,xml标记都缩写了
最近最后一个接口,他们的格式很严格必须是如下格式 <message> <age>20</age> <name>张三</name> </ ...
- bootstrap js插件
导入JavaScript插件 Bootstrap除了包含丰富的Web组件之外,如前面介绍的下拉菜单.按钮组.导航.分页等.他还包括一些JavaScript的插件. Bootstrap的JavaScri ...
- 新站如何做SEO及注意事项
最近公司做了新网站,完成后运营优化的工作就落在我身上了,由于之前也没有.就去网上百度了一下,上了各种论坛查阅大牛的博客.自己也总结了一些要点,在这里和大家分享一下.新网站大家可以点击查看牛羊养殖在线. ...
- 转:使用 Docker 搭建 Java Web 运行环境
原文来自于:http://www.codeceo.com/article/docker-java-web-runtime.html Docker 是 2014 年最为火爆的技术之一,几乎所有的程序员都 ...
- Unity3d 与IOS 相互调用
Unity3d 与IOS 相互调用 @灰太龙 群63438968 我用的Unity3d 4.2版本,这一节说一下IOS与U3D的交互! 首先在U3D中写个方法:这个时候导出为ios代码必须是真机,模拟 ...
- 一步一步学习SignalR进行实时通信_8_案例2
原文:一步一步学习SignalR进行实时通信_8_案例2 一步一步学习SignalR进行实时通信\_8_案例2 SignalR 一步一步学习SignalR进行实时通信_8_案例2 前言 配置Hub 建 ...
- HDU 5410 CRB and His Birthday
题目大意: 一个人要去买礼物,有M元.有N种礼物,每件礼物的价值是Wi, 你第i件礼物买k个 是可以得到 Ai * k + Bi 个糖果的. 问怎么才能使得你得到的糖果数目最多. 其实就是完全背包 ...
- 【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别
原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,Hash ...