Как захватить ошибки компиляции из скрипта включения?
Я хочу включить файл в функцию и используя ob_start()
, ob_get_contents()
и т. д. сохранить вывод в файл.
Но если есть ошибка во включенном файле, я хочу:
Чтобы моя функция знала это и захватила его (чтобы он мог справиться с этим изящно)
Не выводить ошибку
Будет set_error_handler
разрешить это?
1 ответ
Для (большинства) не смертельных, да, set_error_handler
можете поймать тех, и вы можете обращаться с ними изящно.
Для фатальных ошибок взгляните на ответ на этот вопрос: PHP: Пользовательский обработчик ошибок - обработка разбора и фатальных ошибок
Теперь, если вы заинтересованы в предотвращении простых ошибок разбора, вы можете использовать runkit_lint_file
расширения runkit, если вы можете установить расширения для вашей установки PHP. [Дополнение к редактированию: то есть, скопируйте файл перед его включением. Ошибки разбора не подлежат восстановлению. Это также можно сделать, запустив php в командной строке с параметром -l. Хотя в зависимости от того, как настроен ваш хост, вам может потребоваться изменить среду для работы опции php командной строки.]
Вот пример с командной строкой php, но я не уверен, что это хороший пример. Разорвано с одного из моих проектов с некоторыми добавленными комментариями.
/**
* Lint and and retrieve the result of a file. (If lint is possible)
* @param $file
* @return Mixed bool false on error, string on success.
*/
function lint_and_include ($file) {
if(is_readable($file)) {
//Unset everything except PATH.
//I do this to prevent CGI execution if we call
//a CGI version of PHP.
//Someone tell me if this is overkill please.
foreach($_ENV as $key=>$value)
{
if($key == "PATH") { continue; }
putenv($key);
}
$sfile = escapeshellarg($file);
$output = $ret = NULL;
//You could modify this to call mandatory includes to
//also catch stuff like redefined functions and the like.
//As it is here, it'll only catch syntax errors.
//You might also want to point it to the CLI php executable.
exec("php -l $sfile", $output, $return);
if($return == 0) {
//Lint Okay
ob_start();
include $file;
return ob_get_clean();
}
else {
return false;
}
}
else {
return false;
}
}
Дополнительные примечания: в этом случае ваш set_error_handler
callback должен регистрировать ошибки, которые он может где-то перехватить, вместо того, чтобы выводить их Если какой-либо из включенного кода может выдавать исключения, вы можете также перехватить их с помощью блока try-catch.