• 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文件的内容:

     代码如下 复制代码

    <?php

         require_once("folder_a/file_a_a.php");

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

    ?>

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

     代码如下 复制代码

    <?php

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

         $x = new X();

         $x.printInfo();

    ?>

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

     代码如下 复制代码

    <?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 中的所有代码,那么我们来看看它运行那些代码?

     代码如下 复制代码

    <?php

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

         $x = new X();

         $x.printInfo();

    ?>

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

     代码如下 复制代码

    <?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很简单用但在使用时大家尽量使用绝对路径了。

  • 相关阅读:
    python爬虫笔记(3-1)re模块
    python爬虫笔记(2-2)xpath解析实例
    python爬虫笔记(2-1)Xpath解析
    python爬虫笔记(1-2)requests模块实例
    python爬虫笔记(1-1)requests模块:请求数据获取响应内容
    小程序上传图片,放大,删除。
    小程序中多个echarts折线图在同一个页面的使用
    vue传值 ---- >> 子传父,$emit()
    vue传值 ---- >> 父传子,props()
    离线webpack创建vue 项目
  • 原文地址:https://www.cnblogs.com/zhanghao1314/p/4949157.html
Copyright © 2020-2023  润新知