Open musicode opened 10 years ago
在网上搜索二者的区别,有非常多的文章,其中很多内容都已过时,下面我将分条阐述:
已过时
require 和 include 只是一种语言特性,不是函数(正确)
正确
框架普遍的写法是 require 'x.php',而不是 require('x.php'),具体请参考 php 官方文档
报错机制不同(正确)
这里测试两种错误,第一种是加载的文件不存在,第二种是加载的文件内部报错(以语法错误为例)。
文件不存在:require 报 fatal error,include 报 warning 文件内部报错:require 和 include 都报 parse error
require 预加载,include 按需加载(错误)
错误
关于这一条,最常见的论述是当不进入 if 分支时,是否加载文件。
根据实际测试,如果不进入分支,require 和 include 都不会加载文件。
require 和 include 加载的文件不能使用 return(错误)
require 和 include 的文件都可以 return,比如配置文件通常使用全局 return 一个关联数组的方式。
require 适合加载静态内容,include 适合加载脚本(错误)
框架几乎很难见到 include,基本都是 require,所以这条十分可笑。
如上所述,不论从美观(跟其他语言保持一致,比如 nodejs、python),还是严谨的角度来看,require 都是上选。
require 都是上选
require_once 和 include_once,基本跟 require/include 一样,唯一的不同是,require/include_once 需要查询一次已加载的文件列表,判断是否存在,不存在再加载。
但是 require/include_once 自身实现有一些问题,具体可参考 《再一次, 不要使用(include/require)_once》 。
从提升加载速度的角度来看,判断文件是否加载也是需要时间的,所以综合考虑还是不要使用为好。
不要使用为好
综上,推荐只使用 require。
只使用 require
分析之前,先根据我的前端经验,讲讲前端 AMD 规范的加载机制,它会把各种形式的路径,比如绝对路径、相对路径(相对自身)、别名等,格式化成绝对路径,再进行加载。用绝对路径统一所有路径,便于简单处理,而且内部存储的最终形式是绝对路径的映射表,这样才能实现最快的查找速度。
require 解析路径的顺序如下:
require
千万要注意
绝对路径的查找速度最快,所以框架经常用以下方式进行加载:
require __DIR__ . '/x.php';
这里需要详细说明第 2、3 步,最好跟着例子亲手写一遍,加深印象。
测试目录结构如下:
root |- 1.php |- subdir |- 2.php
1.php
require './subdir/2.php';
2.php
echo '2.php';
fatal error
因此,相对路径是相对 当前工作目录,而不是 脚本当前目录
测试以下代码:
echo get_include_path();
它会打印出一个以 PATH_SEPARATOR 分割的字符串,第一项是 .,表示 当前工作目录,查找顺序是从左到右,一旦找到就不再往后找了(类似环境变量 PATH 的查找方式)。
.
解析 include_path 的过程是,由 include_path 和 当前脚本目录 组成一个目录数组,遍历查找,为了证明这一点,举个例子:
测试目录结构:
root |- 1.php |- t.php |- subdir |- 2.php |- t.php
可以看到 root 和 root/subdir 都有一个 t.php,我们用它来测试优先加载哪个目录下的文件。
require 't.php';
root/t.php
echo 'root';
root/subdir/t.php
echo 'root/subdir';
可见优先加载 当前工作目录 下的文件。
因为 include_path 默认第一项是 当前工作目录,所以这种说法也不严谨,当我们改变 include_path 时,第一项可能就变化了。
在实现框架级别的加载时,为了提升速度,会把新的路径加到 include_path 前面,比如:
// 获取新添加的路径数组 $includePaths = require __DIR__ . '/include_paths.php'; // 把新的路径添加到 include_path 的开头 array_push($includePaths, get_include_path()); // 重新设值 set_include_path(join(PATH_SEPARATOR, $includePaths));
关于网上的文章
在网上搜索二者的区别,有非常多的文章,其中很多内容都
已过时
,下面我将分条阐述:require 和 include 只是一种语言特性,不是函数(
正确
)框架普遍的写法是 require 'x.php',而不是 require('x.php'),具体请参考 php 官方文档
报错机制不同(
正确
)这里测试两种错误,第一种是加载的文件不存在,第二种是加载的文件内部报错(以语法错误为例)。
文件不存在:require 报 fatal error,include 报 warning 文件内部报错:require 和 include 都报 parse error
require 预加载,include 按需加载(
错误
)关于这一条,最常见的论述是当不进入 if 分支时,是否加载文件。
根据实际测试,如果不进入分支,require 和 include 都不会加载文件。
require 和 include 加载的文件不能使用 return(
错误
)require 和 include 的文件都可以 return,比如配置文件通常使用全局 return 一个关联数组的方式。
require 适合加载静态内容,include 适合加载脚本(
错误
)框架几乎很难见到 include,基本都是 require,所以这条十分可笑。
如上所述,不论从美观(跟其他语言保持一致,比如 nodejs、python),还是严谨的角度来看,
require 都是上选
。require_once 和 include_once,基本跟 require/include 一样,唯一的不同是,require/include_once 需要查询一次已加载的文件列表,判断是否存在,不存在再加载。
但是 require/include_once 自身实现有一些问题,具体可参考 《再一次, 不要使用(include/require)_once》 。
从提升加载速度的角度来看,判断文件是否加载也是需要时间的,所以综合考虑还是
不要使用为好
。综上,推荐
只使用 require
。加载机制
分析之前,先根据我的前端经验,讲讲前端 AMD 规范的加载机制,它会把各种形式的路径,比如绝对路径、相对路径(相对自身)、别名等,格式化成绝对路径,再进行加载。用绝对路径统一所有路径,便于简单处理,而且内部存储的最终形式是绝对路径的映射表,这样才能实现最快的查找速度。
require
解析路径的顺序如下:千万要注意
绝对路径的查找速度最快,所以框架经常用以下方式进行加载:
这里需要详细说明第 2、3 步,最好跟着例子亲手写一遍,加深印象。
解析相对路径
测试目录结构如下:
1.php
2.php
2.php
fatal error
因此,相对路径是相对 当前工作目录,而不是 脚本当前目录
解析 include_path
测试以下代码:
它会打印出一个以 PATH_SEPARATOR 分割的字符串,第一项是
.
,表示 当前工作目录,查找顺序是从左到右,一旦找到就不再往后找了(类似环境变量 PATH 的查找方式)。解析 include_path 的过程是,由 include_path 和 当前脚本目录 组成一个目录数组,遍历查找,为了证明这一点,举个例子:
测试目录结构:
可以看到 root 和 root/subdir 都有一个 t.php,我们用它来测试优先加载哪个目录下的文件。
1.php
2.php
root/t.php
root/subdir/t.php
可见优先加载 当前工作目录 下的文件。
因为 include_path 默认第一项是 当前工作目录,所以这种说法也不严谨,当我们改变 include_path 时,第一项可能就变化了。
在实现框架级别的加载时,为了提升速度,会把新的路径加到 include_path 前面,比如: