【问题标题】:PHP Include Always FailsPHP 包含总是失败
【发布时间】:2011-10-29 15:31:36
【问题描述】:
  • Apache HTTP Server 2.2.21 和 SuExec 下的 VirtualHosts
  • 通过 fcgid 的 PHP 5.3.8
  • 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 也没有区别。然而,我可以通过从错误日志中复制粘贴并cding 来验证该文件是否存在于该确切位置......

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

编辑

  • 相同目录下的文件结果相同。
  • Apache 和 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 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>

【问题讨论】:

标签: php apache2 mod-fcgid suexec


【解决方案1】:

首先确保文件存在...

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

【讨论】:

  • 包含的文件不需要对浏览器可见。
【解决方案2】:

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

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

【讨论】:

  • 文件夹的权限很好。 set_include_path 无效。
  • 代码中没有配置的问题。你能检查 .htaccess 文件中的 AddHandler 指令吗?
  • 我没有.htaccess。我已将我的虚拟主机配置添加到 OP。
【解决方案3】:

它总是对我有用->

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

试一试!

[已编辑]

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

【讨论】:

  • 已经排除了斜线/缺少斜线;另外,这是 Linux,所以分隔符总是斜杠。请阅读 OP。
【解决方案4】:

DerfK 在 ServerFault nailed it:这是一个 open_basedir 限制。

【讨论】:

    【解决方案5】:

    转回发帖solution

    我没有意识到 open_basedir 不受安全模式关闭的影响 - 它正在查看 /srv/http/ 但不是 /srv/www/,这将是 /srv/www/hostname/public/includes/content/ 的包含目录。

    【讨论】:

      猜你喜欢
      • 2015-06-12
      • 2013-07-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多