2009-09-28 5 views
3

Я недавно получил сообщение об ошибке при развертывании приложения. Он использовал «is_readable» в пути внутри пути include, но тот, который был ограничен «open_basedir». Это дало мне фатальную ошибку. Есть ли еще одна функция, которую я мог бы использовать, чтобы увидеть, может ли файл быть включен, прежде чем включать его?PHP is_readable problem with open_basedir


Edit: это работает, но как я могу обнаружить, если ошибка была потому, что включают в себя несостоявшимся или из-за какой-то ошибки внутри включаемого файла?

try { 
include 'somefile.php'; 
$included = true; 
} catch (Exception $e) { 
// Code to run if it didn't work out 
$included = false; 
} 
+0

Если ваша фреймворк выбрасывает все как исключение, как вы прокомментировали ниже, вы можете войти в функцию обработчика ошибок и проверить, какая степень серьезности возникшей ошибки. Или настройте свой собственный сверху. На самом деле нет ограничений на количество настраиваемых обработчиков ошибок, которые вы можете использовать. –

+0

На самом деле вы даже можете получить серьезность от самого ErrorException, но как это может помочь мне определить, вызвало ли фактическое включение ошибку? –

ответ

2

Вы можете «попробовать» это;)

<?php 

function exceptions_error_handler($severity, $message, $filename, $lineno) { 
    throw new ErrorException($message, 0, $severity, $filename, $lineno); 
} 
set_error_handler('exceptions_error_handler'); 
try { 
    include 'somefile.php'; 
    $included = true; 
} catch (Exception $e) { 
    // Code to run if it didn't work out 
    $included = false; 
} 
echo 'File has ' . ($included ? '' : 'not ') . 'been included.'; 
?> 

Если он не работает, $ включено будет установлена ​​истина, а затем ложно в улове. Если это сработало, $ включено остается правдой.

+2

Приятная попытка: p, но ложное включение не генерирует исключение, а классическую ошибку. –

+0

Ах, да. Я когда-то использовал обработчик ошибок, который забрасывал ошибки PHP в исключения. Функция exceptions_error_handler ($ severity, $ message, $ filename, $ lineno) { throw new ErrorException ($ message, 0, $ severity, $ filename, $ lineno); } set_error_handler ('exceptions_error_handler'); Не знаю, если это хорошая идея. –

+0

Infact, используемая мной инфраструктура исключает все стандартные ошибки PHP в качестве исключений. –

1

Вы можете проверить значение open_basedir rescriction (если он установлен), используя

ini_get('open_basedir'); 

будет возвращать допустимый путь (ы) или пустую строку, если не установлена.

Edit:

Проверка пути включают в ограничение open_basedir безопасный путь может пойти что-то вроде этого:

if (strlen(ini_get('open_basedir')) > 0) 
{ 
    $includeFile = 'yourInclude.php'; 
    $includePath = dirname(realpath($includeFile)); 

    $baseDirs = explode(PATH_SEPARATOR, ini_get('open_basedir')); 
    foreach ($baseDirs as $dir) 
    { 
     if (strstr($includePath, $dir) && is_readable($includeFile)) 
     { 
      include $includeFile; 
     } 
    } 
} 

Но не стесняйтесь, чтобы улучшить это, если вы видите ярлык.

+0

Да, но это говорит мне, если файл включен, так как вы иногда можете это сделать даже с файлами, которые находятся за пределами основы, верно? –

+0

То, как работает ограничение на основе (с моей точки зрения), состоит в том, что все файлы выше каждого из них должны быть как минимум доступными, поэтому вам нужно будет проверить, находится ли файл, который вы пытаетесь включить, в ваши основанные на вас, как только это будет сделано использование is_readable без фатальной ошибки. Я просто ухожу из офиса, я могу опубликовать соответствующий пример позже, если вам нужна дополнительная помощь. –

0

Вы можете попробовать использовать stat для достижения такого же эффекта, как is_readable, который, как я слышу, очень глючит, когда установлен базовый каталог.

+1

Ошибочное поведение is_readable исправлено с PHP 5.2. Для более старых версий предпочтительнее использовать stat –

Смежные вопросы