PHP中你应该知道的require()文件包含的正确用法

以前看一些PHP框架源码的时候,很奇怪在文件包含的时候,会用dirname(__FILE__)来拼凑文件路径,不知道这样做有什么好处,后来终于发现了其中的缘由。

我们来看一个简单的例子:

有a,b,c三个PHP文件。a.PHP在网站根目录,b.PHP在b文件夹下——b/b.PHP,c.PHP在c文件夹下——c/c.PHP。有些混乱?看图就一目了然了:

a.PHP 和 b.PHP 都包含了 c.PHP,最后 c.PHP 包含了d文件夹下的一个PHP文件——d/d.PHP

我们先来看a.PHP

rush:PHP;">

很简单的代码,打印输出后,包含了c/c.PHP,接着,我们需要看c/c.PHP

rush:PHP;">

打印输出 "this is c.PHP,is required by a.PHP",$file_name是在a.PHP中定义的变量。在最后,包含了d.PHP。因为d文件夹在当前c.PHP文件的上一层,所以,按照常理,我们会理所当然的把路径写成 "../d/d.PHP"。但是很遗憾,会报错。原因在于,在被包含的文件中如c.PHP,再去包含其他文件,路径是相对于最外层的父文件来说的,也就是相对于a.PHP,可以理解为因为你被我包含了,所以你要以我为准。看起来很玄乎,原理其实很简单:你可以把 require('c/c.PHP'); 看成是c/c.PHP文件里的代码,这样我们的a.PHP看起来可以是这个样子:

rush:PHP;">

到此,你可以看到,我们要包含d/d.PHP文件时,刚才的路径是不是错误的了?因为,现在是在a.PHP代码里,我们是相对于a.PHP文件来说的,当然,路径应该是 require('d/d.PHP'); 才对了。我们修改代码如下:

rush:PHP;"> echo "this is a.php";
echo "";

// require('c/c.php');
$c_file_name = 'c.php';

echo 'this is c.php,is required by ' . $file_name;
echo "";

require('d/d.php');
?>

此时,你还没有领悟到深意,需要往下看,我们再看b/b.PHP

rush:PHP;"> require('../c/c.php');
?>

不需要解释了吧,没啥问题,但是当你把 require('../c/c.PHP'); 换成 c/c.PHP 里面的代码的时候,你就会发现问题了,注意,我们刚才修改了c/c.PHP里的代码,把 require('../d/d.PHP'); 改成了 require('d/d.PHP'); 看下面包含进来后的代码

rush:PHP;"> // require('../c/c.php');
$c_file_name = 'c.php';
echo 'this is c.php,is required by ' . $file_name;
echo "";
require('d/d.php');
?>

那么,相对于 b/b.PHP 来说,require('d/d.PHP'); 的路径错了,应该是 require('../d/d.PHP'); 才对。你回去修改 c/c.PHP 中的require路径,但是不对呀,你改了之后,b/b.PHP可以正常运行了,但是 a/a.PHP 又不行了,是不是,它们共用 c/c.PHP ,牵一发动全身,怎么办呢。

这个时候,我们回到文章开头提到的 dirname(__FILE__),这可是个好东西,可以完全解决以上问题。用了它,就可以不用关心包含你的文件是哪个文件、在哪个路径下面了,不需要顾虑父文件所在的层级,因为,dirname(__FILE__)可以相对于当前文件指定路径。也就是说,我们需要将我们的 c/c.PHP 中的 require 路径换为:

rush:PHP;"> echo 'this is c.php,is required by ' . $file_name;
echo "";

require(dirname(FILE) . '/../d/d.php');
?>

这里,我们只需要把 c/c.PHP 作为参照,相对于它来说,d/d.PHP 在上一层。这样,就只有一个标准了,那就是,以我为准,管你包含我,还是他包含我,我只以我自己为准,我要包含的文件只相对于我自己而言了。

对于 dirname(__FILE__) 不明白的同修,请google,很简单。

好了,PHP技术分享到此结束,有任何疑问或有错误之处,请留言。话说,这是我的第一个标准技术博文。第一篇是水文,第二篇是准技术,今天终于写了篇技术的,欧也。

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...