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

时间: 2024-08-17 08:27:38

php require_once用法与相对目录要谨慎的相关文章

jQuery 事件用法详解

jQuery 事件用法详解 目录 简介 实现原理 事件操作 绑定事件 解除事件 触发事件 事件委托 事件操作进阶 阻止默认事件 阻止事件传播 阻止事件向后执行 命名空间 自定义事件 事件队列 jquery中文文档 简介 jquery 之所以成为最受欢迎的前端库,很大一部分是得益于它的事件具有良好的语义,优秀的兼容性,并且便于管理和扩展. 在这里我会介绍 jquery 事件的一些比较基础的用法. 实现原理 jquery 事件脱胎于浏览器的 addEventListener (W3) 和 attac

linux笔记:目录处理命令ls,mkdir,cd,pwd,rmdir,cp,mv,rm

linux命令的格式:命令 [-选项] [参数]例:ls -la /etc 命令:ls命令所在路径:/bin/ls功能:显示目录文件用法:ls [-aldh] []参数:-a 查看所有文件,包括隐藏文件.linux的隐藏文件是以"."开头的,如果我们要把一个文件设置成隐藏文件,在新建文件时以"."开头即可.-h 按易读的方式显示文件大小,如K,M,G,而不是以字节为单位.-l 显示详细信息.7个详细信息分别是:文件类型和权限,文件被调用次数,所有者,所属组,文件大小

PHP-流的概念与详细用法

Stream是PHP开发里最容易被忽视的函数系列(SPL系列,Stream系列,pack函数,封装协议)之一,但其是个很有用也很重要的函数.Stream可以翻译为"流",在Java里,流是一个很重要的概念. 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部文件等.根据流的方向又可以分为输入流和输出流,同时可以在其外围再套上其它流,比如缓冲流,这样就可以得到更多流处理方法. PHP里的流

bower_home用法

bower home 功能:在系统默认浏览器中打开包的bower.json中homepage字段对应的主页 用法一:不指定包名 dulin@IT01010030921 /e/website/jquery-plugins/bower_components/mockjs (master) $ bower home 说明:不指定包名的用法需要将目录切换到该包所在的根目录下 用法二:指定包名,在哪个目录无所谓 [email protected] /e/website/jquery-plugins (ma

Linux学习之路(2-1)文件、目录与磁盘格式

第一章 Linux的文件权限与目录配置 Linux中的大小写是不一样的. 一.用户与用户组 1.文件所有者(own):功能:安全防护 2.用户组(group):每个账号都可以有多个用户组的支持 3.其他人(other) 默认情况下,所有的系统上的账号与一般身份用户,还有root的相关信息,都记录在/etc/passwd这个文件内 个人的密码都记录在etc/shadow这个文件下.所有的组名都记录在/etc/group内. 二.Linux文件权限 1.Linux文件属性.查看属性命令:ls -al

shell脚本编程之变量的小用法

变量赋值 ${parameter:-word}:如果parameter为空或未定义,则变量展开为"word":否则,展开为parameter的值: ${parameter:+word}:如果parameter为空或未定义,不做任何操作:否则,展开为"word"值: ${parameter:=word}:如果parameter为空或未定义,则变量展开为"word",并将展开后的值赋值给parameter: ${parameter:?word}:如果

Apache Rewrite 中文详解

这几天一直在研究Apache的重写规则,虽然网上有很多教程,不过发现大部分都是抄袭一个人的,一点都不全,所以我想写一个简单的易于理解的教程,我学习.htaccess是从目录保护开始的,这个也比较简单,网上也有一些编辑器可以选择,这儿就不说了,教程从绑定域名到子目录开始,网上也有教程,大部分都是抄袭一个人的,我在这儿解说一下,教程写法是这样的: RewriteEngine OnRewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$RewriteCond %{REQU

使用.htaccess实现apache URL重定向

一.什么是URL重定向? URL重定向(URL redirection,或称网址重定向或网域名称转址),是指当使用者浏览某个网址时,将他导向到另一个网址的技术. 二.URL重定向怎么配置? 1)首先需要apache开启重定向,修改httpd.conf配置: 1 查找: 2 Options FollowSymLinks 3 AllowOverride None 5 改为: 6 Options FollowSymLinks 7 AllowOverride All 2)去掉下面的注释 LoadModu

转--htaccess语法教程 apache服务器伪静态规则教程

转自:http://blog.csdn.net/qingli518/article/details/9118361 htaccess语法教程apache服务器伪静态规则教程 注:如果你是为了找Discuz!论坛的为静态规则的话,其实不用看这里,Discuz!的后台有个链接点进去直接Copy就是了.PHPwind的我就不知道了,没用过,后台应该也有吧. 这几天一直在研究Apache的重写规则,虽然网上有很多教程,不过发现大部分都是抄袭一个人的,一点都不全,所以我想写一个简单的易于理解的教程,我学习