- Apache HTTP Server 2.2.21 with VirtualHosts under SuExec
- PHP 5.3.8 通过 fcgid
- Arch Linux 2011.08.19
我正在从共享主机迁移到VPS。我在移动之前运行良好的代码,但现在在这一行失败了:
require_once($_SERVER['DOCUMENT_ROOT'] . 'includes/content/header.php');
错误日志说:
PHP 致命错误:require_once((:打开失败 必需的 '/srv/www/hostname/public/include/content/header.php' (include_path='.:/美元/股票/梨'( /srv/www/hostname/public/index.php 在第 3 行
我尝试了没有文档根部分的同一行,有和没有./
等,但没有运气。与require
、include_once
或include
也没有区别。但是,我可以通过从错误日志中复制粘贴并cd
到该文件来验证该文件是否存在于该确切位置......
但为了绝对确定,我测试了include
和file_exists
的返回值 - 它们都返回 false。然而,所有文件都由 SuExec 用户/组录制,并且权限组合无济于事(对目录或文件(;尝试从 644 到 777。这是怎么回事?
编辑:
- 同一目录中的文件结果相同。
- Apache和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 admin@hostname.com
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>
首先确保文件存在...
- 然后尝试使用www.hostname/public/include/content/header.php(如果您使用这将是本地的东西localhost/public/include/content/header.php(
- 如果这没有加载,则您的问题安装或您的文件已损坏。
- 尝试从其他地方加载标头
您是否检查了包含该文件的文件夹的权限?
文件夹应具有 apache(或运行 http-server 的任何用户(的读取权限。
您是否尝试添加路径以包含路径?
$path = '/includes/content';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
http://php.net/manual/en/function.set-include-path.php
它总是对我有用->
if ( DIRECTORY_SEPARATOR == '/' )
{
$path = dirname(__FILE__).'/';
}
else
{
$path = str_replace('\', '/', dirname(__FILE__)).'/';
}
试一试!
[已编辑]
使用 dirname(( 函数始终有效! $path = dirname(__FILE__).'/';
问题可能出在您的服务器上。不在编程(脚本(中。
ServerFault的DerfK指出了这一点:这是一个open_basedir
限制。
旋以发布解决方案:
我没有意识到open_basedir
不受安全模式关闭的影响——它正在查找/srv/http/
但不/srv/www/
,这将是/srv/www/hostname/public/includes/content/
的包含目录。