深入解析PHP工作目录机制:如何正确调用脚本文件
PHP 的当前工作目录为被调用的脚本文件所处的目录。若您的文件呈现为如下这般:

/A
foo.php
tar.php
B/
bar.php
如果您调用 foo.php,比如 http://example.com/foo.php,那么工作目录将会是 /A/。如果您调用 bar.php,例如 http://example.com/B/bar.php,此时工作目录将为 /A/B/。
这是它变得棘手的所在之处。我们来假设 foo.php 是如下这样的:
require_once( 'B/bar.php' );
?>
bar.php 是:
require_once( 'tar.php');
?>
如果调用了 foo.php,那么 bar.php 就能成功调用 tar.php。因为 tar.php 和 foo.php 在同一个目录里,且这个目录恰好就是工作目录。如果改为调用 bar.php,就会失败。
通常你会在所有文件中看到:
require_once( realpath( dirname( __FILE__ ) ).'/../../path/to/file.php' );
或者使用配置文件:
// config file
define( "APP_ROOT", realpath( dirname( __FILE__ ) ).'/' );
其余文件使用:
require_once( APP_ROOT.'../../path/to/file.php' );
我喜欢这样做:
require_once(dirname(__FILE__)."/../_include/header.inc");
这样你的路径总是可以相对于当前文件位置。
我在大部分时间里会使用类似这样的东西。它能够做到的是拥有一个基本的入口点,通过这个入口点可以加载所有其他的代码。这些代码定义了一个常量,这个常量引用了项目的根,也就是 dirname(__FILE__)。
define("ROOT",dirname(__FILE__).'/' );
然后你需要知道的是路径相对于 root 的位置,即:
require(ROOT . "/lib/tool/error.php");
笔记不应在开头带有“../”的路径,这些路径不是相对于文件的,而是相对于所在位置的,这样会产生错误的代码。
cd foo
php bar/baz.php
出现了一个错误,称找不到该文件。
cd bar
php baz.php
-> suddenly working.
重要的
如果您使用“../”符号,那么您就完全不清楚 PHP 的包含路径。并且您只会考虑运行它的人所处的位置。
我在每一页的顶部都包含了这段代码:
//get basic page variables
$self=$_SERVER['PHP_SELF'];
$thispath=dirname($_SERVER['PHP_SELF']);
$sitebasepath=$_SERVER['DOCUMENT_ROOT'];
包含全局设置、变量以及包含项。
include_once("$sitebasepath/globals/global.include.php");
include 和 require 这两者都可以采用相对路径或者完整的根路径。我更倾向于使用完整路径,并且像上面的 inlcude 语句那样进行所有的引用。这样做能够让我输入一个通用的变量 $sitebasepath 来处理那些可能因机器而异的账户特定信息,之后只需要输入 webroot 的路径就可以了。/globals/whatever_file.php
我在某种表单中使用了 $self 变量,这种表单有可能会调用我来处理数据输入。
希望有所帮助。
如果您具备足够的访问权限,那就尝试去修改整个站点的 PHP 设置中的 include_path。倘若您无法做到这一点,那么您要么得通过相同的 PHP 脚本(例如借助 Apache mod_rewrite )来路由每一个请求,要么就必须使用设置 include_path 的“初始化”脚本。
$includeDir = realpath(dirname(__FILE__) . '/include');
ini_set('include_path', $includeDir . PATH_SEPARATOR . ini_get('include_path'));
包含该文件后,使用相对于包含目录的路径:
require_once '../init.php'; // The init-script
require_once 'MyFile.php'; 包含 /include/MyFile.php 。
因为 require 和 require_once 跟 include 和 include_once 极为相似,所以所有文档都被发布在 php.net 上“include”函数的文档区域里,并且这些文档来自该页面。
用于包含的文件首先在每个 include_path 条目相对于当前工作目录的位置处查找,接着在当前脚本的目录中查找。如果您的 include_path 为 libraries,当前工作目录是 /www/。您包含了 include/a.php ,并且此文件中包含“b.php”。那么 b.php 会先在 /www/libraries/ 中查找,接着在 /www/包括/ 中查找。如果文件名是以./开头,那么仅在当前工作目录中查找;如果文件名是以../开头,那么也仅在当前工作目录中查找。
您可以通过在命令行执行“php -i”去找到所有当前的包含路径。您能够编辑 php.ini 文件中的包含路径,还可以通过 ini_set() 来进行编辑。倘若 CLI 不太方便,您还可以在页面中运行 php_info() 函数,以打印环境变量。
我看到评估路径的唯一地方是您正在编辑的那个文件。我未曾遇到过问题,不过要是你有问题的话,或许你会想要提供更多的信息,比如 PHP 版本、操作系统等。
原始的 GET 或 POST 中所请求的 PHP 文件的路径,本质上就是该脚本的“工作目录”。并且,任何“包含的”脚本以及任何“必需的”脚本,也都会将其继承下来,作为它们自己的工作目录。
我会在 require 语句里使用绝对路径,或者对 PHP 的 include_path 进行修改,从而在我的应用程序中包含我可能需要使用的任何路径,这样就能节省额外的输入。你可以在 php.ini 中找到它。
include_path 包含“/and/another/one”
我不知道它在这个特定实例中能否帮助您。如果您需要知晓特定文件运行的路径,那么像 FILE 和 DIR 这样的神奇常量是能够发挥作用的。
看一下函数 getcwd。