PHP 文件包含分析

测试脚本a.php:

  1. <?php
  2. include_once("b.php");
  3. echo "=====\n";
  4. include_once("b.php");
  5. echo "=====\n";
  6. include_once("c.php");

目录结构:
a.php
b.php

include_path 的 = .;/usr/local/lib/php

strace -e file php a.php
——————————
open("a.php", O_RDONLY)                 = 3     // 打开a.php
getcwd("/usr/home/junjie2", 4096)       = 18
lstat64("/usr/home/junjie2/a.php", {st_mode=S_IFREG|0644, st_size=108, …}) = 0
lstat64("/usr/home/junjie2", {st_mode=S_IFDIR|0777, st_size=36864, …}) = 0
lstat64("/usr/home", {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
lstat64("/usr", {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
getcwd("/usr/home/junjie2", 4096)       = 18     // get current working directory (这个就是include_path 中的 "." )
lstat64("/usr/home/junjie2/./b.php", {st_mode=S_IFREG|0644, st_size=7, …}) = 0   // 找见了
lstat64("/usr/home/junjie2/b.php", {st_mode=S_IFREG|0644, st_size=7, …}) = 0
open("/usr/home/junjie2/b.php", O_RDONLY) = 3
=====
getcwd("/usr/home/junjie2", 4096)       = 18  // 这次包含没有真实的文件操作,因为包含过了的文件PHP自己都知道,可以使用get_included_files()来查看,所以就不需要再lstats和open了
=====
getcwd("/usr/home/junjie2", 4096)       = 18      // get current working directory (这个就是include_path 中的 "." )
lstat64("/usr/home/junjie2/./c.php", 0xbf904350) = -1 ENOENT (No such file or directory)  // 没找见
lstat64("/usr/local/lib/php/c.php", 0xbf904350) = -1 ENOENT (No such file or directory)     // 去include_path 中的 "/usr/local/lib/php" 下面找还没找见
lstat64("/usr/home/junjie2/c.php", 0xbf904350) = -1 ENOENT (No such file or directory)    // 去脚本所在的目录下面找此次查找和include_path 无关
getcwd("/usr/home/junjie2", 4096)       = 18  // 这里又查一次,why?
lstat64("/usr/home/junjie2/./c.php", 0xbf9042a0) = -1 ENOENT (No such file or directory)
lstat64("/usr/local/lib/php/c.php", 0xbf9042a0) = -1 ENOENT (No such file or directory)
lstat64("/usr/home/junjie2/c.php", 0xbf9042a0) = -1 ENOENT (No such file or directory)
getcwd("/usr/home/junjie2", 4096)       = 18
lstat64("/usr/home/junjie2/c.php", 0xbf906390) = -1 ENOENT (No such file or directory) // 这次查找可能是报错的时候查的
open("/usr/home/junjie2/c.php", O_RDONLY) = -1 ENOENT (No such file or directory)

结论:
1. 先查找 include_path 设置的目录; 其中的 "." 代表的不是脚本所在目录,而是脚本运行时的cwd(当前工作目录),这个目录是可以通过chdir修改的
2. 如果include_path 中查不到,则再查找脚本所在目录,这个和是否设置了include_path 无关
3. ini_set("include_path", ""); 第二个参数不能为空,为空的话就没有任何作用

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据