在大型的Web项目中, include_path是一个模块化设计的根本中的根本(当然,现在也有很多基于autoload的设计, 这个不影响本文的探讨), 但是正是因为include_path, 经常会让我们遇到一些因为没有找到正确的文件而导致的看似”诡异”的问题.

也就有了如下的疑问:

include_path是怎么起作用的?

如果有多个include_path顺序是怎么样的?

什么情况下include_path不起作用?

今天, 我就全面的介绍下这个问题, 先从一个例子开始吧.

如下的目录结构:

root

├ 1.php

├ 3.php

└ subdir

├ 2.php

└ 3.ph

在1.php中:

ini_set(“include_path”, “.:path_to_subdir”);

require(“2.php”);

?>

而在2.php中:

require(“3.php”);

?>

而在root目录下的3.php打印出”root”, 在subdir目录下的3.php打印出”subdir”;

现在, 我的问题来了:

1. 当在root目录下运行1.php, 会得到什么输出?

2. 在subdir下运行上一级目录的1.php, 有会得到什么输出?

3. 当取消include_path中的当前目录path(也就是include_path=”path_to_subdir”), 上面俩个问题又会是什么输出?

PHP中的include_path

PHP在遇到require(_once)/include(_once)的指令的时候, 首先会做如下的判断:

要包含的文件路径是绝对路径么?

如果是, 则直接包含, 并结束.

如果不是, 进入另外的逻辑(经过多次调用, 宏展开后进入_php_stream_fopen_with_path)寻找此文件

接下来, 在_php_stream_fopen_with_path中, 会做如下判断:

要包含的文件路径是相对路径么(形如./file, ../dir/file, 以下用”目录相对路径代替”)?

如果是, 则跳过include_path的作用逻辑, 直接解析相对路径(随后单独介绍)

会根据include_path,和当前执行文件的path组成一个待选的目录列表, 比如对于文章前面的例子来说, 会形成一个如下的待选列表

“.:path_to_subdir:current_script_dir

然后, 依次从待选列表头部开始, 根据DEFAULT_DIR_SEPARATOR(本文的环境是”:”)取出待选列表中的一个路径, 然后把要包含的文件名附加在这个路径后面, 进行尝试. 如果成功包含, 则返回, 否则继续下一个待选路径.

到现在为止, 我们已经可以回答我开头提出的3个问题了.

1. 因为在root目录下执行, 所以在1.php中包含2.php的时候, include_path的第二个待选路径起了作用(path_to_subdir), 找到了path_to_subdir/2.php, 而在2.php包含3.php的时候, 当前工作目录是root下, 所以在包含3.php的时候, include_path的第一个待选路径”.”(当前工作目录)下就找到的匹配的文件, 所以得到的输出是”root”.

2. 同1, 只不过当前的路径是subdir, 所以得到的输出是”subdir”.

3. 因为没有了当前路径为include_path, 所以在root目录下运行的时候2.php中包含3.php的时候, 是path_to_subdir起了作用, 所以无论在root还是subdir都将得到”subdir”的输出.

而如果在2.php中清空include_path,

ini_set(“include_path”, ”);

require(“3.php”);

?>

那么将会是current_script_dir起作用, 而这个时候current_script_dir是2.php的路径, 所以还是会得到”subdir”的输出.

目录相对路径

在使用目录相对路径的情况下, 相对路径的基点, 永远都是当前工作目录.

为了说明在目录相对路径下的情况,我们再看个列子, 还是上面的目录结构, 只不过1.php变成了:

ini_set(“include_path”, “/”);

require(“./subdir/2.php”);

?>

2.php变成了:

require(“./3.php”);

?>

如果在root目录下执行, 2.php中寻找3.php将会在当前目录的相对路径下寻找, 所以得到的输出是”root”, 而如果是在subdir下执行上一级目录的1.php(php -f ../1.php), 将会因为在subdir下找不到”./subdir/2.php”而异常退出.

后记

1. 因为使用include_path和相对路径的情况下, 性能会和寻找的次数有关, 最坏的情况下, 如果你有10个include_path, 那么最多可能会重试11次才能找到要包含的文件, 所以, 在能使用绝对路径的情况下最好使用绝对路径.

2. 因为目录相对路径的basedir, 永远都是当前工作路径, 如果要使用, 需要和实际部署路径相关, 所以实际使用的很少(当然, 也有借助chdir来完成的模块).

3. 在模块化的系统设计中, 一般应该在模块内, 通过获取模块的部署路径(dirname(__FILE__), php5.3以后更是提供了__DIR__常量)从而使用绝对路径.

include php 相对路径_PHP include_path 分析相关推荐

  1. java面试宝典 之 物流配送路径优化问题分析与算法解读

    物流配送路径优化问题分析与算法解读(一)         去年五一跳蚤以后,一直在一家公司参与物流配送软件开发的相关工作,负责的工作内容包括物流配送路径优化这一块.关于物流配送这一专业领域,自己以前也 ...

  2. java 获取发布后的路径问题_Java中的路径问题实例分析

    Java中的路径问题实例分析 前言:关于Java中得路径问题,网上有很多获取的答案,我这篇文章的目的在于说明获取路径时一些不常见的概念.在实际应用中使用的比较多的就是,当前路径和配置文件的路径(其他文 ...

  3. 基本路径测试案例分析

    基本路径测试案例分析 Q:请使用基本路径测试对该程序进行测试: 二分查找 public int binSearch(int arr[], int objectValue) {int left = 0; ...

  4. php 加载一个文件路径_PHP文件加载过程

    1.文件的路径问题 我们之前也用过一些有关文件路径问题的知识,比如: .... php中,有3种路径 相对路径: 有两个特定符号(特定路径)来决定的路径形式: ./ :表示当前目录,也就是当前网页所在 ...

  5. linux c 获取绝对路径各种方法分析

    昨天肚腩群里有人问LINUX下C如何获取程序绝对路径.初看这问题,肚腩觉得很简单啊,就用getcwd或者argv[0]就可以了.写了个程序试试, #include <unistd.h>in ...

  6. 数据可视化高级部分:如何使用轨迹地图对路径数据进行分析

    前言 当我们需要分析路径数据时,轨迹图是个很好的呈现方式.在 Tableau 中,可以利用经纬度数据来实现轨迹图.在本文中我们分享两个轨迹图案例,帮助大家做出更为酷炫的可视化图. 以下链接为博主精心整 ...

  7. php 匹配图片路径_php正则匹配图片路径原理与方法

    下面我来给大家介绍在php正则匹配图片路径原理与实现方法,有需要了解的朋友可进入参考参考. 提取src=里面的图片地址还不足够,因为不能保证那个地址一定是绝对地址,完全的地址,如果那是相对的呢?如果地 ...

  8. linux内核体系学习路径_Linux内核分析(一)linux体系简介|内核源码简介|内核配置编译安装...

    从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底,同时在博文中如果那些地方有问题还请各位大神为我讲解. 今天我们会分析到以下内容: 1. Linux体系结构简介 ...

  9. php include的路径问题,php7中include有相对路径无法打开

    目前相对路径,可以用 include"./1.php";) 上一个相对路径,可以用 include"../1.php";) 一开始采用php的include包括 ...

最新文章

  1. JZ2440学习总结2
  2. (转)AS3 Socket
  3. Opencv中的阈值函数
  4. Java高新技术 枚举
  5. flink source和sink
  6. VS2010平台下OpenCV编译和安装
  7. C++中回调函数(CALLBACK)初探
  8. Visdom:Python可视化神器
  9. nodejs 端口被占解决
  10. Java中创建线程池的正确方法
  11. kuangbin14数论解析
  12. 新手从零学电脑组装与维修视频教程
  13. css表格一行删除线,EXCEL电子表格一行中间画一条删除线怎么画/excel表格如何划掉数据...
  14. IntelliJ IDEA 2020 提示“Unmapped Spring configuration files found.Please configure Spring facet.”解决办法
  15. python中def demo是什么意思_python中def是什么意思
  16. 程序员为什么要写博客
  17. 类似新浪微博中取消关注的弹出确认框
  18. OpenFoam安装swak4Foam
  19. 第二章:Djgo后台管理
  20. Java学习指南从入门到入土

热门文章

  1. 利用这10个工具,你可以写出更好的Python代码
  2. 记一次面试过程中的Python编程题
  3. Spark中foreachRDD、foreachPartition和foreach解读
  4. Hadoop 生态系列之 1.0 和 2.0 架构
  5. DIV CSS在不同IE版本和FF以及Chrome中的兼容性差异解决方法(推荐)
  6. ExtJS的extend(Ext Designer的使用)
  7. 【Tensorflow】TF中的字符串tf.string
  8. 解决方法:AttributeError: module ‘torchtext.data‘ has no attribute ‘Field‘
  9. LeetCode —— 365. 水壶问题(Python3)
  10. 吴恩达深度学习 —— 2.6 更多导数的例子