PHP Включить всегда терпит неудачу - PullRequest
1 голос
/ 29 октября 2011
  • Apache HTTP Server 2.2.21 с виртуальными хостами под 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/includes/content/header.php' (include_path = '.: / usr / share / pear') в /srv/www/hostname/public/index.php в строке 3

Я попробовал ту же самую строку без корневой части документа, с ./ и без него и т. Д., Но безуспешно. Никаких различий с require, include_once или include тоже нет. Тем не менее, я могу проверить, что файл существует в этом точном месте, вставив копию из журнала ошибок и cd в него ...

Но, чтобы быть абсолютно уверенным, я проверил возвращаемые значения include s, а также 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() не имеет никакого эффекта.
  • Запуск require через php-cgi непосредственно из командной строки возвращает внутреннюю ошибку сервера, в то время как include возвращает пустой вывод; выполнение через php возвращает пустой вывод.

Вот мой конфиг vhost:

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

Ответы [ 5 ]

0 голосов
/ 15 декабря 2011

Возвращаясь к сообщению о решении :

Я не осознавал, что open_basedir не зависел от отключения безопасного режима - он искал в /srv/http/, но не /srv/www/, который был бы каталогом для /srv/www/hostname/public/includes/content/.

0 голосов
/ 30 октября 2011

DerfK на ServerFault прибил его : это было ограничение open_basedir.

0 голосов
/ 29 октября 2011

Сначала убедитесь, что файл существует ...

  • Затем попробуйте перейти к нему с помощью www.hostname / public / includes / content / header.php (если вы используете что-то местное было бы локальный / государственный / включает / содержание / header.php)
  • Если это не загружается или что-то не так с вашим установка или ваш файл поврежден.
  • Попробуйте загрузить заголовок откуда-то еще
0 голосов
/ 29 октября 2011

Мне это всегда работает ->

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

попробуй!

[Изменено]

Использование функции dirname () всегда работает! $path = dirname(__FILE__).'/'; возможно, проблема в вашем сервере. Не в программировании (сценарий).

0 голосов
/ 29 октября 2011

Вы проверяли разрешение папок, связанных с этими файлами?

Папка должна иметь разрешение на чтение для apache (или любого пользователя, который запускает http-сервер).

Вы пытались добавить путь, чтобы включитьпуть?

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

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

...