Home >php教程 >php手册 >php require_once用法与相对目录要谨慎

php require_once用法与相对目录要谨慎

WBOY
WBOYOriginal
2016-06-13 09:56:171275browse

文章介绍了大家在 php开发中会常常碰到的一个关于require_once用法,有需要的朋友可参考一下。

wwwroot   //网站根目录 绝对路径为: F:/wwwroot

-- folder_a // 文件夹A

   file_a_a.php

   file_a_b.php

   file_a_c.php

-- folder_b // 文件夹B

   file_b_a.php

   file_b_b.php

   file_b_c.php

-- index.php

*************************************************************

这个目录层次已经很清楚了:

wwwroot为根目录,下面有index.php文件和folder_a,folder_b两个文件夹

这两个文件夹分别有3个php文件

先来看index.php文件的内容:

 代码如下 复制代码

     require_once("folder_a/file_a_a.php");

     echo "文件folder_a_a.php被包含成功";

?>

再来看folder_a/folder_a_a.php文件的内容:

 代码如下 复制代码

     require_once("../folder_b/file_b_a.php");

     $x = new X();

     $x.printInfo();

?>

最后再来看看folder_b/folder_b_a.php文件的内容:

 代码如下 复制代码

     class X{

          function printInfo(){

               echo 'success;

          }

     }

?>

ok 如果我现在直接运行 floder_a/file_a_a.php

那么会输出: success

如果我运行 wwwroot下的index.php

那么会报错,原因是找不到包含文件:file_b_a.php

但是如果我在所有的require_once()中加入 dirname(__FILE__).'/'

那么无论运行 file_a_a.php 还是 index.php 都可以正常输出

*********************************************************

问题:

我第一次使用的是相对路径,所以重复包含的时候就出错了

而我第二次使用的是绝对路径,所以不出错.可是我还是有点疑惑:

我先分析了以下使用相对路径会出错的原因:

我运行index.php,它能找到 folder_a目录,也能找到该目录下的file_a_a.php,于是它就把 folder_a/file_a_a.php 里的内容复制到了index.php 的第一行(包含语句的那行),然后再继续运行(也就是运行包含过来的内容),因此此时等于是在index.php中运行 file_a_a.php 中的require_once('../folder_b/file_b_a.php'); 它根据当前index.php的位置去找这个路径文件(file_b_a.php),当然找不到啦,所以它出错了.

可是我使用绝对路径的时候不是一样的道理吗?可为什么它就不出错?可能这句话大家有点不解了,我来详细说明(根据程序的运行顺序来说明).

程序先运行 index.php(注意此时我加上了 dirname(__FILE__),所以当前是绝对路径),

index.php先运行第一句代码:require_once(dirname(__FILE__).'/'.'folder_a/file_a_a.php');

dirname(__FILE__) 就是 f:/wwwroot/ 所以这句代码包含的路径也就是:

f:/wwwroot/folder_a/file_a_a.php

这个路径是正确的,因此没问题是吧

ok 第一步正确完成

然后它就把 file_a_a.php 中的代码复制到的 index.php 的这个地方:

然后仍然继续运行: 这是也就是在index.php 中运行file_a_a.php 中的所有代码,那么我们来看看它运行那些代码?

 代码如下 复制代码

     require_once(dirname(__FILE__).'/'."../folder_b/file_b_a.php");

     $x = new X();

     $x.printInfo();

?>

对就是这些,需要注意的是,这些代码已经被复制到了index.php,也就是说,现在index.php的内容实际上就变成了:

 代码如下 复制代码

     require_once(dirname(__FILE__).'/'."../folder_b/file_b_a.php");

     $x = new X();

     $x.printInfo();

     echo "文件folder_a_a.php被包含成功";

?>


我们来看个注意事项

假设有如下三个文件, c.php a.php b.php 对应的存放目录为:localhost/ localhost/ localhost/demo

 代码如下 复制代码

c.php

require_once("a.php");
require_once("demo/b.php");
B::demo();a.php
class A
{
}

b.php的内容比较有意思,因为它自己要继承 CLASS A 所以自己把a.php也引入进去了

 代码如下 复制代码

require_once("../a.php");
class B extends A
{
    public static function demo()
    {
    echo "xx";
    }
}

执行localhost/c.php 系统报错,报错信息如下
Warning: require_once(../a.php) [function.require-once]: failed to open stream: No such file or directory in F:wwwdemob.php on line 2
Fatal error: require_once() [function.require]: Failed opening required '../a.php' (include_path='.;C:php5pear') in F:wwwdemob.php on line 2但是,惊奇的发现,如果去掉b.php里面的require_once语句,执行正常,那么一定是require_once语句定义多了吗?原因就是Class A重定义了两次?可是不会啊。如果我只在c.php里面加require_once(‘a.php’);这条语句,哪怕我写两遍也是没错的,那到底是咋回事呢?
原因就是,b.php定义的目录和c.php执行文件的目录层级不一致,导致在c.php里面require_once语句有两条。使其相当于

 代码如下 复制代码

require_once("a.php");
require_once("../a.php");
class B extends A
{
    public static function demo()
    {
    echo "xx";
    }
}
B::demo();

原因找到了,因为在c.php里面,其相对目录 “..”就是 c.php的上一层了,导致文件找不到报错。
所以,我们的结论是,在 PHP 里面,使用require_once的时候,存在不同层级关系,且有相对目录的使用那么一定要谨慎,小心。


require_once很简单用但在使用时大家尽量使用绝对路径了。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn