PHP致命错误:打开所需文件失败

9
我有一个名为'sess-start.php'的脚本,它位于我的httpdocs目录中的/include目录中。
我的网站继续出现此错误:
[Fri Mar 25 14:52:24 2011] [error] [client 12.3.3.3] PHP致命错误:require() [function.require]:无法打开所需的'/includes/sess-start.php'(include_path ='。:')在/var/www/vhosts/site.com/httpdocs/page.php的第4行,引用者:https://www.site.com/ 尽管www.site.com/includes确实存在。怎么回事!
编辑1
这些是可能包含其他require或include语句的包含/需要文件。相对路径将不起作用,请不要建议这样做。
我的.htaccess文件已将所有包含路径指向站点根目录: php_value include_path .:/var/www/vhosts/site.com/httpdocs
编辑2
并非我所有的包含或必需的脚本都包含在单个目录中,因此建议仅将/includes目录放置在include_path中也被否定了(反过来还会在Windows机器上引起问题)
更新
也许对一个真实例子的澄清可以帮助解决我们团队正在尝试解决的问题:
在一个页面上,用户可以输入多个选项,下一页进行必要的计算,并基于此将客户路由到许多潜在选项,所有这些选项都会导致类似于DB条目的require语句。
然后,在db条目(或其他操作)中,如果一切顺利,成员可能已经选择在他/她的操作基础上接收电子邮件确认。此require语句位于第二个require(db insert)中,但与第二个不同,并因此导致冲突,因为第一个文件处理链接时不正确。
硬编码绝对路径或甚至根据每个页面设置适当的包含路径是“可以”的,但它会禁用我们团队在文件之间使用dreamweaver(或任何执行相同操作的程序)进行热链接的能力,因为在测试环境中运行时无法识别“站点根”。

你有读取那个文件的权限吗? - emco
@EmCo - 是的,我有。如果我移除前面的斜杠(这样使它变成相对路径并且对我没有用),那么它就可以正常工作。 - JM4
3个回答

8

您的路径以斜杠 (/) 开头。

在符合 POSIX 标准的系统中,如果您的路径以斜杠开头,则表示它是一个绝对路径。第一个斜杠代表文件系统的根目录。

从您的路径中删除斜杠,那么您就会得到相对于 page.php 的路径。

编辑:由于相对路径不起作用,您可以使用 dirname(__FILE__) 来获取当前文件所在目录的绝对路径。

require(dirname(__FILE__) . '/includes/sess-start.php');

3
@JM4:这有缺陷……只需执行 realpath('/'),您很快就能明白。无论在何种环境下,如果路径以斜杠 / 开头,则它始终是 绝对路径。因此,在 Windows 下,/includes/sess-start.php 指向 C:\includes\sess-start.php。在 *nix 下,它指向 /includes/sess-start.php。不相信我?realpath()一下吧。所有三个答案都说了同样的事情:使你的路径成为绝对路径。也许我们没有错……做一个批量替换。 - Andrew Moore
1
@Andrew Moore - 说得好。再次强调,我并不想挑起争端,只是想指出所有面临的问题,并看看是否有其他解决方案(例如相对路径建议,虽然有效但不适用)。如果我在初始问题中给出了完整的更新,可能会更清楚明白。 - JM4
1
@JM4:这是针对超链接的,而不是针对PHP包含(这就是为什么它在“关于链接和导航”部分中)。在超链接上下文中,您的文件层次结构的根是您的Web服务器的根。在PHP的上下文中,也就是物理文件系统上下文中,根是您的文件系统的根目录。 - Andrew Moore
1
@JM4:引用自PHP文档中的一句话:“如果定义了路径——无论是绝对路径(以Windows上的驱动器号或\开头,在Windows/Unix/Linux系统上以/开头)还是相对于当前目录(以...开头)——那么include_path将被完全忽略。例如,如果文件名以../开头,则解析器将在父目录中查找所请求的文件。” - Andrew Moore
1
值得注意的是,如果您遇到此错误,则您的路径实际上可能只是错误的。 - Andrew
显示剩余10条评论

6
你需要使用相对路径。当你的文件名以/开头时,PHP会认为你是指根目录。正确的前缀应该是./
include('./includes/sess-start.php');

如果您希望所有路径都相对于文档根目录,则以下是一种常见方法:

include("$_SERVER[DOCUMENT_ROOT]/includes/sess-start.php");

我不想使用相对路径 - 这将破坏几个包含/需要。 - JM4
@JM4 - 然后使用 include('includes/sess-start.php');,这样 PHP 就会使用 include_path。 - Mark Baker
@mario 和 @mark baker - 不管怎样,理论上来说上述应该可以工作。移除前导斜杆是“欺骗”系统的行为。在 Windows 环境下,正斜杠可以工作(并且是 Dreamweaver 会在任何相对于其站点根目录的文件之前放置的字符)。 - JM4
1
不应该这样。 / 始终 表示绝对路径,而不是虚拟目录基础。 Dreamweaver 已经误导了你。 - mario
1
@JM4:请再次阅读手册,http://www.php.net/manual/en/ini.core.php#ini.include-path 其他问题都已经得到解答。 - mario
显示剩余8条评论

1

看起来您需要从include行中删除前导斜杠。

编辑:为了解决您的问题。在预处理文件或某些常见包含文件中,创建一个如DOCROOT的常量。您可以从__FILE__常量动态确定它。

然后:

include(DOCROOT.'myfile.php');

个人而言,我会尝试设置以避免这种情况的发生。


当进行其他子包含/需要时,相对路径无法正常工作。 - JM4
没有相对路径无法工作的理由。设置您的include_path与某个基本目录一起,并使所有内容相对于该目录工作。如果您坚持使用绝对路径,请查看__FILE__常量并从中获取目录名称。 - Matthew
请查看(http://stackoverflow.com/questions/5434450/what-is-proper-way-to-declare-required-elements-within-php-in-different-director)有关在PHP中声明不同目录中的必需元素的正确方式。该问题提供的示例中不支持相对路径。 - JM4
@JM4,我绝不建议使用“../”来开始一个包含路径。无论源文件在哪里,我都会使它们相对于您的包含位置。 - Matthew
在大多数情况下,相对路径不是问题,但在使用子需求时会导致很大的麻烦。这样的一个例子是,一个子目录使用一个连接类,然后在该连接类内调用另一个需要包含该连接常量的 require。 - JM4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接