以前看一些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:

<?php 

    $file_name = 'a.php';

    echo "this is a.php";
echo "<hr>"; require('c/c.php'); ?>

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

<?php
$c_file_name = 'c.php'; echo 'this is c.php, is required by ' . $file_name;
echo "<hr>"; require('../d/d.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看起来可以是这个样子:

<?php
$file_name = 'a.php'; echo "this is a.php";
echo "<hr>"; // require('c/c.php');
$c_file_name = 'c.php'; echo 'this is c.php, is required by ' . $file_name;
echo "<hr>"; require('../d/d.php');
?>

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

<?php
$file_name = 'a.php'; echo "this is a.php";
echo "<hr>"; // require('c/c.php');
$c_file_name = 'c.php'; echo 'this is c.php, is required by ' . $file_name;
echo "<hr>"; require('d/d.php');
?>

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

<?php
$file_name = 'b.php'; echo "this is b.php";
echo "<hr>"; require('../c/c.php');
?>

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

<?php
$file_name = 'b.php'; echo "this is b.php";
echo "<hr>"; // require('../c/c.php');
$c_file_name = 'c.php'; echo 'this is c.php, is required by ' . $file_name;
echo "<hr>"; 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 路径换为:

<?php
$c_file_name = 'c.php'; echo 'this is c.php, is required by ' . $file_name;
echo "<hr>"; require(dirname(__FILE__) . '/../d/d.php');
?>

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

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

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

PHP中require()文件包含的正确用法的更多相关文章

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

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

  2. php学习笔记6--php中的文件包含 include,require,include_once,require_once

    php中的文件包含 include,require,include_once,require_once 文件包含:是指将一个文件的内容包含进另外一个文件,有利于代码的复用等.php中文件包含指令有4个 ...

  3. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  4. C#中dynamic、ExpandoObject 的正确用法

    原文地址:http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4.0的新特性.dynam ...

  5. luci 中require函数包含的路径

    在 lua 脚本中常用的包含某个文件就是 require 函数. 例如: #!/usr/bin/lua                     // 表明使用的是lua脚本,像shell脚本一样 lo ...

  6. PHP中的文件包含

    在PHP中,包含文件有两种方式:include和require.这两种方式的功能一样,只有一个区别,就是使用require包含一个文件时,如果出现错误,脚本不会继续执行:而如果使用include包含, ...

  7. Linux系统中虚拟设备文件的各种实用用法

    大家好,我是良许. 大家知道,在 Linux 下,一切皆文件,对于设备文件也是如此.我们在工作的过程中,经常会看到 /dev/null 这个玩意,那它到底是什么呢? 专业地讲,/dev/null 是一 ...

  8. Android 中.aar文件生成方法与用法

    https://i.cnblogs.com/EditPosts.aspx?opt=1 无论是用Eclipse还是用Android Studio做android开发,都会接触到jar包,全称应该是:Ja ...

  9. 彻底删除 Git 项目中的文件(BFG Repo-Cleaner 用法)

    一些时候由于开发初期经验不足和贪图方便, 会把一些不应该提交到 Git 的文件上传到 Github, 带来一系列安全问题, 更有可能是把一些大文件上传到 GitHub 上, 导致项目非常臃肿, 每次 ...

随机推荐

  1. Matlab中矩阵的平方和矩阵中每个元素的平方介绍

    该文章讲述了Matlab中矩阵的平方和矩阵中每个元素的平方介绍.   设t = [2 4 2 4] 则>> t.^2 ans = 4 164 16 而>> t^2 ans = ...

  2. input之placeholder与行高的问题

    我们实现一个输入框的视觉的时候为了保持其各种各样的兼容性: 1.鼠标要跟文字一样高度. 2.文字要居中对齐. 3.还要有placeholder 第一个目标,当实现一个高度为40像素的高度输入框时,为了 ...

  3. mongoDB2--mongoDB的下载和安装。

    mongdb安装(1)安装准备我们在Linux环境下来安装mongodb,如果没有Linux操作系统的童鞋,可以使用Vmware虚拟机安装一个Linux虚拟环境来学习.这里就不再赘述.我们到mongo ...

  4. JavaScript(6)——事件1.0

    ---恢复内容开始--- 事件 好不容易回到正轨,好好学习,天天向上.今天写的是事件,感觉内容蛮多的,所以分了两篇写,主要写了事件流.事件处理程序.事件对象.恩,明天还会再有一篇,哈哈哈.我努力的!我 ...

  5. cocoaPods的安装方法

    1.打开终端 2.先升级Gem sudo gem update --system 3.切换cocoapods的数据源 [先删除,再添加,查看] gem sources --remove https:/ ...

  6. jquery各版本区别

     jquery版本区别:          1.3一般功能够 1.4.2一般功能够而且稳定 1.7+比较新特性 2不支持老IE 兼容的话最好选 1.x.稳定性就用1.7或者1.4,其中1.4的体积相对 ...

  7. 转:java.io.IOException: Exceeeded maximum number of redirects: 5 解决版本

    Jmeter运行的时候出现的重定向超过n次的问题: When trying to test a Silverlight application, I get the below error. Has ...

  8. HDU 5543 Pick The Sticks

    背包变形.与普通的背包问题不同的是:允许有两个物品可以花费减半. 因此加一维即可,dp[i][j][k]表示前i个物品,有j个花费减半了,总花费为k的情况下的最优解. #pragma comment( ...

  9. angularjs上传图片插件使用

    一. angurlajs 相关 远程 jar 包 https://code.angularjs.org/angular-1.0.1.min.js 二. 正文 1. html 部分 <!-- 需要 ...

  10. 使用OpenCV查找二值图中最大连通区域

    http://blog.csdn.net/shaoxiaohu1/article/details/40272875 使用OpenCV查找二值图中最大连通区域 标签: OpenCVfindCoutour ...