Как получить от PHP-FPM код ошибки, отличный от 200, при PHP Fatal error?
Дано: Nginx 1.4.1, PHP-FPM 5.3.27
При возникновении в PHP фатальной ошибки вебсервер возвращает текст ошибки и код 200.
Окей, прописываем в nginx по советам лучших собаководов:
fastcgi_catch_stderr «PHP Fatal error:»;
Теперь при фатальной ошибке возвращается код 502 Bad Gateway, но на этот раз текста ошибки нет.
Нужно: возвращать ошибочный код и выводить саму ошибку в браузер, как это делает апач. Если вдобавок можно будет сменить код 502 на что-то более вменяемое, будет совсем хорошо.
Не совсем понятно чего Вы хотите, если свои error page то nginx.org/ru/docs/http/ngx_http_core_module.html#error_page
Или вы про fastcgi_intercept_errors спрашиваете?
Если про эту опцию, то достаточно указать fastcgi_intercept_errors on;
Нет, я не хочу свои error_page. И спрашиваю не про intercept_errors.
На пальцах:
1. создаём PHP-файл с вызовом несуществующей функции. Запрашиваем в браузере. Видим в браузере код ответа 200 и текст Fatal error: Call to undefined function fatal_erro() in /www/public_html/test.php on line 2
2. Прописываем fastcgi_catch_stderr «PHP Fatal error:»;
Видим в браузере код 502, но в тексте страницы нет вывода PHP про fatal error, срабатывает стандартная error_page
А нужно совместить 1 и 2: должен отдаться код 50x, но в тексте должно быть Fatal error: Call to undefined function fatal_erro() in /www/public_html/test.php on line 2
Так делает апач и в общем-то это то, как всё должно быть. Но в nginx почему-то я придумать как извернуться не могу, чтобы сделать то что мне нужно.
То что вы хотите обычно на стороне фреймверков осуществляется. допустим такое поведение yii представляет, на стороне nginx отключаются страницы ошибок и yii генерирует страницу ошибок.
Напиши хендлер для фатал эррора, который будет отдавать и текст, и правильный код ошибки: www.php.net/set-error-handler
Подключается хендлер к любому файлу директивой auto_prepend_file.
это абсолютно точно не вариант, но даже если бы оно и подходило идеологически, то не заработало бы:
The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.
function fatalErrorHandler()
{
$lastError = error_get_last();
if (isset($lastError["type"]) && $lastError["type"]==E_ERROR) {
// do something with the fatal error
}
}
...
register_shutdown_function('fatalErrorHandler');
Данная ошибка должна решаться на стороне nginx. В дефолтном поведении все честно — ему бэкенд отдал текст(html) — он честно вернул ответ 200.
Как, тоже гадаю, к сожалению((
Впрочем кастомный обработчик ошибок в php это хоть и костыль — но вполне себе решение для php-fpm.