PHP 包含总是失败

发布于 2024-12-12 14:12:45 字数 2897 浏览 0 评论 0原文

  • 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 行

我在没有文档根部分、有或没有 ./ 等的情况下尝试了同一行,但没有成功。与 requireinclude_onceinclude 也没有区别。然而,我可以通过从错误日志复制粘贴并 cd 到该文件来验证该文件是否存在于该确切位置......

但为了绝对确定,我测试了 的返回值>include 以及 file_exists——它们都返回 false。然而,所有文件都由 SuExec 用户/组 chown'd,并且权限组合没有帮助(在目录或文件上);已尝试从 644 到 777。这是怎么回事?

编辑

  • 与同一目录中的文件相同的结果。
  • 阿帕奇SuExec 错误日志未报告任何内容。
  • 安全模式在 php.ini 中设置为“关闭”。
  • dirname(__FILE__)exec('pwd') 返回与 $_SERVER['DOCUMENT_ROOT'] 相同的结果,但不带尾部斜杠。
  • freadfile_get_contentsrealpath(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 cding to it…

But just to be absolutely sure, I tested the return values of the includes 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__) and exec('pwd') return the same as $_SERVER['DOCUMENT_ROOT'] but without the trailing slash.
  • fread, file_get_contents, and realpath(dirname(__FILE__)) all return false.
  • set_include_path() has no effect.
  • Running require via php-cgi directly from the command line returns Internal Server Error while include returns blank output; running either via php 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一袭水袖舞倾城 2024-12-19 14:12:45

首先确保文件存在...

  • 然后尝试使用导航到它
    www.hostname/public/includes/content/header.php (如果您使用
    当地的东西
    localhost/public/includes/content/header.php)
  • 如果没有加载,则您的文件有问题
    安装或您的文件已损坏。
  • 尝试从其他地方加载标头

First make sure the file exists...

  • Then try to navigate to it using
    www.hostname/public/includes/content/header.php (if your using
    something local it would be
    localhost/public/includes/content/header.php)
  • If that does not load either something is wrong with your
    installation or your file is corrupt.
  • Try loading the header from somewhere else
赤濁 2024-12-19 14:12:45

您是否检查了包含该文件的文件夹的权限?

文件夹应该具有 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

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 ?

$path = '/includes/content';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);

http://php.net/manual/en/function.set-include-path.php

落墨 2024-12-19 14:12:45

它总是对我有用 ->

if ( DIRECTORY_SEPARATOR == '/' )
{
    $path = dirname(__FILE__).'/';
}
else
{
    $path = str_replace('\\', '/', dirname(__FILE__)).'/';
}

尝试一下!

[编辑]

使用 dirname() 函数总是有效! $path = dirname(__FILE__).'/'; 也许问题出在您的服务器上。不在编程(脚本)中。

It always works to me ->

if ( DIRECTORY_SEPARATOR == '/' )
{
    $path = dirname(__FILE__).'/';
}
else
{
    $path = str_replace('\\', '/', dirname(__FILE__)).'/';
}

give a try!

[EDITED]

using dirname() function always works! $path = dirname(__FILE__).'/'; perhaps the problem is in your server. Not in the programming (script).

心凉 2024-12-19 14:12:45

DerfK 位于 ServerFault 解决了:这是一个 open_basedir 限制。

DerfK over at ServerFault nailed it: it was an open_basedir restriction.

能否归途做我良人 2024-12-19 14:12:45

回过头来发布解决方案

我没有意识到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/.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文