PHP中require和include路径问题详解
1 绝对路径、相对路径和未确定路径
相对路径
相对路径指以.开头的路径,例如
复制代码代码如下:
./a/a.php (相对当前⽬录)
../common.inc.php (相对上级⽬录),
绝对路径
绝对路径是以 / 开头或者windows下的 C:/ 类似的盘符开头的路径,全路径不⽤任何参考路径就可以唯⼀确定⽂件的最终地址。例如
复制代码代码如下:
/apache/wwwroot/site/a/a.php
c:/wwwroot/site/a/a.php
未确定路径
凡是不以 . 或者 / 开头、也不是windows下盘符:/ 开头的路径,例如
复制代码代码如下:
a/a.php
common.inc.php,
开始以为这也是相对路径,但在php的include/require包含机制中,这种类型的路径跟以 . 开头的相对路径处理是完全不同的。require './a.php' 和 require 'a.php' 是不同的!
下⾯分析这三种类型包含路径的处理⽅式:⾸先记住⼀个结论:如果包含路径为相对路径或者绝对径,则不会到
include_path(php.ini中定义的include_path环境变量,或者在程序中使⽤set_include_path(...)设置)中去查该⽂件。
测试环境说明
2. 相对路径:
相对路径需要⼀个参考⽬录才能确定⽂件的最终路径,在包含解析中,不管包含嵌套多少层,这个参考⽬录是程序执⾏⼊⼝⽂件所在⽬录。
⽰例1
A中定义  require './b/b.php';  // 则B=[SITE]/app/test/b/b.php
B中定义  require './c.php';    // 则C=[SITE]/app/test/c.php 不是[SITE]/app/test/b/c.php
⽰例2
A中定义  require './b/b.php';  // 则B=[SITE]/app/test/b/b.php
B中定义  require '../c.php';  // 则C=[SITE]/app/c.php  不是 [SITE]/app/test/c.php
⽰例3
A中定义  require '../b.php';  //则B=[SITE]/app/b.php
B中定义  require '../c.php';  //则C=[SITE]/app/c.php  不是 [SITE]/c.php
⽰例4:
A中定义  require '../b.php';  // 则B=[SITE]/app/b.php
B中定义  require './c/c.php';  / /则C=[SITE]/app/test/c/c.php  不是 [SITE]/app/c/c.php
⽰例5
A中定义  require '../inc/b.php';  // 则B=[SITE]/app/inc/b.php
B中定义  require './c/c.php';    // 则C还是=[SITE]/app/test/c/c.php  不是 [SITE]/app/inc/c/c.php
⽰例6
A中定义  require '../inc/b.php';  // 则B=[SITE]/app/inc/b.php
B中定义  require './c.php';      // 则C=[SITE]/app/test/c.php  不是 [SITE]/app/inc/c.php
3. 绝对路径
绝对路径的⽐较简单,不容易混淆出错,require|inclue 的就是对应磁盘中的⽂件。
require '/wwwroot/xxx/app/test/b.php';    // Linux中
require 'c:/wwwroot/xxx/app/test/b.php';  // windows中
dirname(__FILE__)计算出来的也是⼀个绝对路径形式的⽬录,但是要注意__FILE__是⼀个Magic constants,不管在什么时候都等于写这条语句的php⽂件所在的绝对路径,因此dirname(__FILE__)也总是指向写这条语句的php⽂件所在的绝对路径,跟这个⽂件是否被其他⽂件包含使⽤没有任何关系。
⽰例1
A中定义  require '../b.php';                  // 则B=[SITE]/app/b.php
B中定义  require dirname(__FILE__).'/c.php';  // 则B=[SITE]/app/c.php
⽰例2
A中定义  require '../inc/b.php';              // 则B=[SITE]/app/inc/b.php
B中定义  require dirname(__FILE__).'/c.php';  // 则B=[SITE]/app/inc/c.php 始终跟B在同⼀个⽬录
结论:不管B是被A包含使⽤,还是直接被访问include和contain
B如果 require dirname(__FILE__).'/c.php';    // 则始终引⽤到跟B在同⼀个⽬录中的 c.php⽂件;
B如果 require dirname(__FILE__).'/../c.php'; // 则始终引⽤到B⽂件所在⽬录的⽗⽬录中的 c.php⽂件;
B如果 require dirname(__FILE__).'/c/c.php';  // 则始终引⽤到B⽂件所在⽬录的c⼦⽬录中的 c.php⽂件;
4. 未确定路径
⾸先在逐⼀⽤include_path中定义的包含⽬录来拼接[未确定路径],到存在的⽂件则包含成功退出,如果没有到,则⽤执⾏require语句的php⽂件所在⽬录来拼接[未确定路径]组成的全路径去查该⽂件,如果⽂件存在则包含成功退出,否则表⽰包含⽂件不存在,出错。未确定路径⽐较容易搞混不建议使⽤。
5. 解决⽅案
由于“相对路径”中的“参照⽬录”是执⾏⼊⼝⽂件所在⽬录,“未确定”路径也⽐较容易混淆,因此最好的解决⽅法是使⽤“绝对路径”; 例如b.php的内容如下,⽆论在哪⾥require b.php都是以b.php的路径为参照来require c.php的
$dir = dirname(__FILE__);
require($dir . '../c.php');
或者定义⼀个通⽤函数 import.php,将其设置为“⾃动提前引⼊⽂件”,在php.ini做如下配置
更改配置项(必须)auto_prepend_file = "C: ampp\htdocs\auto_prepend_file.php"
更改配置项(可选)allow_url_include = On
import.php内容如下
复制代码代码如下:
function import($path) {
$old_dir = getcwd();        // 保存原“参照⽬录”
chdir(dirname(__FILE__));    // 将“参照⽬录”更改为当前脚本的绝对路径
require_once($path);
chdir($old_dir);            // 改回原“参照⽬录”
}
这样就可以使⽤import()函数来require⽂件了,⽆论包含多少级“参照⽬录”都是当前⽂件

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。