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

  2. 2018-11-20-UWP-开发中,需要知道的1000个问题

    title author date CreateTime categories UWP 开发中,需要知道的1000个问题 lindexi 2018-11-20 09:28:53 +0800 2018- ...

  3. c++中const变量定义与头文件包含的有关问题

    在使用C++进行程序开发的时候,有个常识我们很熟悉,就是把类的定义写在.h文件中,把类的具体实现写在.cpp文件中.这毫无疑问是对的.但我们很少去思考为什么要这样做,本文结合自己的学习体会,对头文件及 ...

  4. CLR中你想知道的事

    CLR是什么? CLR 公共语言运行时,是一个可由多个语言共同使用的运行环境,核心(内存管理,程序集加载,安全性,异常处理和多线程) Visual Studio是一种编译器,编译器也可称为语法检查器和 ...

  5. Android Toast cancel和show 不踩中不会知道的坑

    说到Android Toast,几乎都很熟悉吧,下面讲讲怎么实现下面几种场景: 1.连续点击一个按钮,每次都产生一个新的Toast并且调用show方法 问题:触发了toast以后,toast内容会一直 ...

  6. PHP文件包含漏洞攻防实战(allow_url_fopen、open_basedir)

    摘要 PHP是一种非常流行的Web开发语言,互联网上的许多Web应用都是利用PHP开发的.而在利用PHP开发的Web应用中,PHP文件包含漏洞是一种常见的漏洞.利用PHP文件包含漏洞入侵网站也是主流的 ...

  7. PHP文件包含漏洞攻防实战

    本文对PHP文件包含漏洞的形成.利用技巧及防范进行了详细分析,并通过一个真实案例演示了如何利用PHP文件包含漏洞对目标网站进行渗透测试,最终成功获取到网站的WebShell. PHP是一种非常流行的W ...

  8. CTF PHP文件包含--session

    PHP文件包含 Session 首先了解一下PHP文件包含漏洞----包含session 利用条件:session文件路径已知,且其中内容部分可控. 姿势: php的session文件的保存路径可以在 ...

  9. web安全原理-文件包含漏洞

    前言 起来吃完早饭就开始刷攻防世界的题,一个简单的文件包含题我竟然都做不出来我服了  拿出买的书开始从头学习总结文件包含漏洞! 一.文件包含漏洞 文件包含漏洞 文件包含函数的参数没有经过过滤或者严格的 ...

随机推荐

  1. Docker实战(十)之分布式处理与大数据平台

    分布式系统和大数据处理平台是目前业界关注的热门技术. 1.RabbitMQ RabbitMQ是一个支持AMQP的开源消息队列实现,由Erlang编写,因以高性能.高可用以及可伸缩性出名.它支持多种客户 ...

  2. 再起航,我的学习笔记之JavaScript设计模式07(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  3. P1006 传纸条

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  4. jQuery带缩略图轮播效果图片切换带缩略图

    以上为效果图 HTML代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /& ...

  5. Openssl自建CA

    查看证书相关指令 # 查看公钥数字证书 openssl x509 -in cacert.pem -noout -text # 查看私钥数字证书 openssl pkcs12 -in client-ce ...

  6. 大数据入门第五天——离线计算之hadoop(上)概述与集群安装

    一.概述 根据之前的凡技术必登其官网的原则,我们当然先得找到它的官网:http://hadoop.apache.org/ 1.什么是hadoop 先看官网介绍: The Apache™ Hadoop® ...

  7. Linux下查看Mysql数据库端口的方法

    mysql 默认的端口是 3306,但是如果在安装的时候,修改了mysql的默认端口的话,可以采用以下方式查看 第一种方法: 直接查看数据库的配置文件 在/etc/mysql/my.cnf(Linux ...

  8. 26-[Boostrap]-全局css样式,组件,控件

    1.全局CSS样式 https://v3.bootcss.com/css/ <!DOCTYPE html> <html lang="zh-CN"> < ...

  9. 提交到开源git时出现:fatal: refusing to merge unrelated histories的解决办法

    解决办法   创建本地库和fetch远程分支这些前面的步骤这里略过.可以自行百度. 解决办法: 1.cmd进入项目的根目录. 2.执行下面的命令:git pull origin master --al ...

  10. P4048 [JSOI2010]冷冻波

    出题人你tm搞笑呢,冰霜新星翻成冷冻波,而且tm就只能打一只小精灵???巫妖王都想来砍死你 首先要搞出每个巫妖能不能打到每一个小精灵,然后二分时间,就能算出每个巫妖可以打的次数,网络流check即可 ...