PHP 包含总是失败
- Apache HTTP Server 2.2.21,
- 通过 fcgid 在 SuExec PHP 5.3.8
- 下使用 VirtualHosts Arch Linux 2011.08.19
我正在从共享主机迁移到 VPS。我在移动之前运行良好的代码,但现在在这一行失败:
require_once($_SERVER['DOCUMENT_ROOT'] . 'includes/content/header.php');
错误日志显示:
PHP 致命错误:require_once():打开失败 必需的“/srv/www/hostname/public/includes/content/header.php” (include_path='.:/usr/share/pear') 在 /srv/www/hostname/public/index.php 第 3 行
我在没有文档根部分、有或没有 ./
等的情况下尝试了同一行,但没有成功。与 require
、include_once
或 include
也没有区别。然而,我可以通过从错误日志复制粘贴并 cd 到该文件来验证该文件是否存在于该确切位置......
但为了绝对确定,我测试了 的返回值>include
以及 file_exists
——它们都返回 false。然而,所有文件都由 SuExec 用户/组 chown'd,并且权限组合没有帮助(在目录或文件上);已尝试从 644 到 777。这是怎么回事?
编辑:
- 与同一目录中的文件相同的结果。
- 阿帕奇SuExec 错误日志未报告任何内容。
- 安全模式在 php.ini 中设置为“关闭”。
dirname(__FILE__)
和exec('pwd')
返回与$_SERVER['DOCUMENT_ROOT']
相同的结果,但不带尾部斜杠。fread
、file_get_contents
和realpath(dirname(__FILE__))
均返回 false。set_include_path()
无效。- 直接从命令行通过
php-cgi
运行require
会返回内部服务器错误,而include
返回空白输出;通过php
运行都会返回空白输出。
这是我的虚拟主机配置:
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "/srv/www/hostname/public/"
ServerName hostname.com
ServerAlias www.hostname.com
SuexecUserGroup hostname hostname
ErrorLog "/srv/www/hostname/logs/error.log"
LogLevel debug
CustomLog "/srv/www/hostname/logs/access.log" combined
<Directory /srv/www/hostname/public>
Order allow,deny
Allow from all
</Directory>
# http://www.linode.com/forums/viewtopic.php?t=2982
<IfModule !mod_php5.c>
<IfModule !mod_php5_filter.c>
<IfModule !mod_php5_hooks.c>
<IfModule mod_actions.c>
<IfModule mod_alias.c>
<IfModule mod_mime.c>
<IfModule mod_fcgid.c>
AddHandler php-fcgi .php
Action php-fcgi /fcgid-bin/php-fcgid-wrapper
Alias /fcgid-bin/ /srv/www/hostname/fcgid-bin/
<Location /fcgid-bin/>
SetHandler fcgid-script
Options +ExecCGI
Order allow,deny
Allow from all
</Location>
ReWriteEngine On
ReWriteRule ^/fcgid-bin/[^/]*$ / [PT]
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</VirtualHost>
- Apache HTTP Server 2.2.21 with VirtualHosts under SuExec
- PHP 5.3.8 via fcgid
- Arch Linux 2011.08.19
I am in the process of migrating from shared hosting to VPS. The code I had ran fine before the move but is now failing at this line:
require_once($_SERVER['DOCUMENT_ROOT'] . 'includes/content/header.php');
Error log says:
PHP Fatal error: require_once(): Failed opening
required '/srv/www/hostname/public/includes/content/header.php'
(include_path='.:/usr/share/pear') in
/srv/www/hostname/public/index.php on line 3
I tried the same line without the document root part, with and without ./
, etc. with no luck. No difference with require
, include_once
, or include
, either. Yet, I can verify that the file exists at that exact location by copy-pasting from the error log and cd
ing to it…
But just to be absolutely sure, I tested the return values of the include
s as well as file_exists
—they all return false. Yet all of the files are chown'd by the SuExec user/group, and no combination of permissions helps (on directories or files); have tried from 644 to 777. What's going on here?
Edit:
- Same result with files in the same directory.
- Apache & SuExec error logs reports nothing.
- Safe Mode is set to "Off" in
php.ini
. dirname(__FILE__)
andexec('pwd')
return the same as$_SERVER['DOCUMENT_ROOT']
but without the trailing slash.fread
,file_get_contents
, andrealpath(dirname(__FILE__))
all return false.set_include_path()
has no effect.- Running
require
viaphp-cgi
directly from the command line returns Internal Server Error whileinclude
returns blank output; running either viaphp
returns blank output.
Here's my vhost config:
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "/srv/www/hostname/public/"
ServerName hostname.com
ServerAlias www.hostname.com
SuexecUserGroup hostname hostname
ErrorLog "/srv/www/hostname/logs/error.log"
LogLevel debug
CustomLog "/srv/www/hostname/logs/access.log" combined
<Directory /srv/www/hostname/public>
Order allow,deny
Allow from all
</Directory>
# http://www.linode.com/forums/viewtopic.php?t=2982
<IfModule !mod_php5.c>
<IfModule !mod_php5_filter.c>
<IfModule !mod_php5_hooks.c>
<IfModule mod_actions.c>
<IfModule mod_alias.c>
<IfModule mod_mime.c>
<IfModule mod_fcgid.c>
AddHandler php-fcgi .php
Action php-fcgi /fcgid-bin/php-fcgid-wrapper
Alias /fcgid-bin/ /srv/www/hostname/fcgid-bin/
<Location /fcgid-bin/>
SetHandler fcgid-script
Options +ExecCGI
Order allow,deny
Allow from all
</Location>
ReWriteEngine On
ReWriteRule ^/fcgid-bin/[^/]*$ / [PT]
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</IfModule>
</VirtualHost>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先确保文件存在...
www.hostname/public/includes/content/header.php (如果您使用
当地的东西
localhost/public/includes/content/header.php)
安装或您的文件已损坏。
First make sure the file exists...
www.hostname/public/includes/content/header.php (if your using
something local it would be
localhost/public/includes/content/header.php)
installation or your file is corrupt.
您是否检查了包含该文件的文件夹的权限?
文件夹应该具有 apache(或任何运行 http-server 的用户)的读取权限。
您是否尝试添加路径以包含路径?
http://php.net/manual/en/function.set-include -path.php
Did you check permission of folders containg that files ?
Folder should has read permission for apache (or any user that runs http-server).
Have you try add path to include path ?
http://php.net/manual/en/function.set-include-path.php
它总是对我有用 ->
尝试一下!
[编辑]
使用 dirname() 函数总是有效!
$path = dirname(__FILE__).'/';
也许问题出在您的服务器上。不在编程(脚本)中。It always works to me ->
give a try!
[EDITED]
using dirname() function always works!
$path = dirname(__FILE__).'/';
perhaps the problem is in your server. Not in the programming (script).DerfK 位于 ServerFault 解决了:这是一个
open_basedir
限制。DerfK over at ServerFault nailed it: it was an
open_basedir
restriction.回过头来发布解决方案:
我没有意识到
open_basedir
不受安全模式的影响关闭 - 它正在查找/srv/http/
但不是/srv/www/
,这将是包含目录/srv/www/hostname/public/includes/content/
。Circling back to post the solution:
I didn't realize that
open_basedir
was unaffected by Safe Mode being off—it was looking in/srv/http/
but not/srv/www/
, which would be the containing directory for/srv/www/hostname/public/includes/content/
.