【问题标题】:PHP include path issues: "./" doesn't link where I expect it?PHP 包含路径问题:“./”没有链接到我期望的位置?
【发布时间】:2011-10-17 00:57:06
【问题描述】:

我正在从头开始开发一个 php MVC 框架,并且在默认 WAMP 部署的相对路径方面遇到了一个有趣的问题......当我开始在框架内编写包含和要求时,问题就出现了......

我的框架入口点位于文档根目录深处的一个文件夹中:

http://localhost/platform/index.php

当我从框架中的任何文件运行以下目录遍历代码时...

$handle = opendir('./');
while ($file = readdir($handle))
{    
    echo $file."<br/>";   
}

...我得到相同的结果:

.
..
ABOUT_APACHE.txt
bin
cgi-bin
CHANGES.txt
conf
error
htdocs
icons
include
INSTALL.txt
lib
LICENSE.txt
logs
manual
modules
NOTICE.txt
OPENSSL-NEWS.txt
OPENSSL-README.txt
README-win32.txt
README.txt
wampserver.conf

即c:/wamp/bin/Apache2.2.17/文件夹的内容

转储 ini_get('include_path') ".;c:/php/pear" ...这很奇怪,因为它是默认的 WAMP 安装,它将 php 放在 c:/wamp/bin/php/php5.3.4 /,据我所知,没有将 PEAR 放在任何地方(我在 php5.3.4 文件夹中没有看到它!)...

第一个问题:为什么 webroot 中任何特定文件中的“./”不是指调用它的文件所在的目录?第一个问题,第二部分:为什么它总是指 wamp-deployed apache 文件夹的根目录,而不管调用文件的位置?

将文件夹的内容转储到“/”会显示:

$INPLACE.~TR
$RECYCLE.BIN
$WINDOWS.~Q
boot
bootmgr
BOOTSECT.BAK
cert.pfx
Config.Msi
Documents and Settings
DVDPATH.TXT
hiberfil.sys
HP
msdia80.dll
MSOCache
pagefile.sys
PerfLogs
Program Files
Program Files (x86)
ProgramData
Recovery
SWSetup
System Volume Information
System.sav
updatedatfix.log
Users
wamp
Windows

第二个问题 - 为什么从我的脚本打开的路径“/”指的是 C:\ 而不是文档根目录(应该是 C:\wamp\www)

最后一个问题 - 我如何配置 PHP 以确保在这些情况下我认为是预期的路径(/ => 文档根目录,./ => 引用脚本的文件夹)实际上是这些引用的路径?

我完全做错了吗?有一次我认为相对路径是参考 CALLED 脚本,或入口点的文件夹,在这种情况下是 c: net 文档似乎另有说明。 PHP.net 表示,使用相对路径(带前导句点)执行函数的 FILE 所在的任何文件夹都应该是相对路径的起始位置。在我的配置中似乎都不是这种情况......

感谢您的宝贵时间!

【问题讨论】:

  • dirname(__FILE__) 会给你执行脚本所在的目录。这有帮助吗?
  • @Chris :感谢您的回复,虽然这肯定会有所帮助,但为什么我的配置很古怪,并且没有像 php.net 描述的那样以及我一直期望的那样?是我做错了什么还是我未能调整的配置设置? ./ = Apache 和 / = C:\ ?!
  • BTW @Chris, dirname(FILE) 完全解决了由 ./ 引用 Apache 的安装根目录而不是当前脚本的工作目录引起的问题,因为我将其设置为名为“ROOT_PATH”的常量,并在应用程序的每个包含中使用它。但是,我仍然很困惑为什么服务器的配置表明“./”不是“脚本的当前工作目录”......我想深入了解一下。如果 ./ 真的意味着“脚本的工作目录”,我应该能够在我的脚本中使用相对链接而不必使用该常量......但它不是......

标签: php frameworks relative-path include-path


【解决方案1】:

第一个问题: 相对包含路径是相对于当前工作目录解释的;当通过 apache + mod_php 运行时,这通常是直接从 apache 调用的顶级脚本的位置。这是一个有点不幸的设计决定,由于 PHP 的流行,它无法撤消。

第二个问题: PHP 最初是为类 Unix 系统编写的,其中/ 表示绝对文件系统根。 Windows 没有这样的东西,因此 PHP 使用次优的东西,即主文件系统上的顶级目录,通常是 C:\

第三个问题:这里有两个解决方案。第一个解决方案:在您的自动前置脚本中设置一个正确的include_path,并且只使用相对名称,例如当您有C:\www\myproject\foo\bar.php 时,将C:\www\myproject\foo 添加到您的include_path,然后添加include 'foo.php'。第二种解决方案:使用dirname() 函数和__FILE__ 超全局的组合来使您的包含明确地相对于当前文件,例如当您想从C:\www\myproject\baz.php 中包含C:\www\myproject\foo\bar.php 时,请使用include dirname(__FILE__) . '/foo/bar.php' 之类的内容。在实践中,您可能会结合使用这两种方法,即使用自动前置脚本中的dirname(__FILE__) 技巧来设置相对于自动前置脚本本身的包含路径。

如果您使用 PHP 的 OOP 功能,您还需要设置一个类自动加载器,这样您就不必显式包含您使用的所有类的定义。

哦,您可能还想阅读文档:http://www.php.net/manual/en/function.include.php

【讨论】:

  • 好的,我得到 C:\ 被“/”引用,因为 Linux 文件系统的根是“/”,而 Windows 文件系统的根是 c:\。我不明白为什么当我从任何文件中执行“./”时,它会引用 Apache 根文件夹?我希望它是 /wamp/www/platform/,index.php 所在的位置?而是 Apache 根目录??
  • . 引用脚本的当前工作目录,它应该是服务器(或虚拟主机)的 Web 根目录,除非您在包含发生之前的任何地方更改它。
  • 我收回我的最后一个声明...我没有看到“。”指的是“脚本的当前工作目录”......这将是 /platform/ 因为 index.php 位于 /platform/... 相反,如问题顶部运行的代码所示,根wamp 部署的 APACHE 安装...
  • 我最初将此标记为答案,但仍然缺少对“为什么不'./' 指示脚本的工作目录并链接到 apache 安装根目录的问题的答案?”这确实是一个 mod-rewrite 场景,但“由 apache 运行的顶级脚本”是 /platform/index.php,我认为这应该导致“./”链接到 /platform/ 而不是 c:/wamp/bin /Apache2.2.17/
  • 这并不重要,因为无论如何您都应该将当前工作目录视为未知目录,至少在您明确设置它之前。否则,如果您包含一些改变 CWD 的内容,然后尝试根据您认为 CWD 的内容包含某些内容,那么您仍然有麻烦。更糟糕的是,如果有人设法在您执行包含之前欺骗您的应用程序更改 CWD,那么您还会遇到非常严重的安全问题。
猜你喜欢
  • 2013-11-09
  • 1970-01-01
  • 2011-02-06
  • 2018-01-13
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多