fsockopen вызывает ошибку FATAL, когда хост недоступен - "невозможно подключиться к"
Когда я вызываю fsockopen для недоступного IP-адреса, PHP останавливает выполнение с FATAL ERROR, как и предполагалось. Но для меня это нормальная ситуация, когда хост недоступен. Есть ли способ, как предотвратить остановку php даже в случае FATAL ERROR, если это предполагаемое поведение?
Я не использую никаких фреймворков, я сама обрабатываю все ошибки. Я регистрирую обработчики как это:
set_error_handler("errorHandler");
register_shutdown_function("fatalErrorHandler");
и обработчики определены так:
function fatalErrorHandler()
{
$error = error_get_last();
if( $error !== NULL) {
$errno = $error["type"];
$errfile = $error["file"];
$errline = $error["line"];
$errstr = $error["message"];
errorHandler($errno, "FATAL: " . $errstr, $errfile, $errline,get_defined_vars(),debug_backtrace());
}
}
function errorHandler($errno, $errstr, $errfile, $errline,$vars,$trace="")
{
// some formatting and checking
file_put_contents(dirname(__FILE__) . "/error/" . gmdate("YmdHis") . str_replace(".","",microtime(true)) . ".err"
,"<error_log_date>" . gmdate("YmdHis") . "</error_log_date><error_log_uid>{$uid}</error_log_uid>
<error_log_str>{$errstr}</error_log_str>
<error_log_file>{$errfile}</error_log_file>
<error_log_line>{$errline}</error_log_line>
<error_log_vars>{$vars}</error_log_vars>
<error_log_trace>{$trace}</error_log_trace>");
return true;
}
1 ответ
Окончательный ответ после того, как вопрос был отредактирован
Вы не знаете о том, что функция завершения вызывается в конце скрипта, независимо от того, произошли ошибки или нет. И даже если это было просто предупреждение, которое не остановило скрипт, сразу же error_get_last() вернет его. Дальше вы просто ставите FATAL:
, закодированный перед сообщением. Вы должны обрабатывать различные типы ошибок, предупреждений и уведомлений здесь.
Проблема заключается в функции выключения, а не fsockopen()
, Функция выключения должна выглядеть так:
register_shutdown_function(function() {
$error = error_get_last();
if($error && $error['type'] === E_ERROR) {
$errno = $error["type"];
$errfile = $error["file"];
$errline = $error["line"];
$errstr = $error["message"];
errorHandler($errno, "FATAL: " . $errstr, $errfile, $errline /* , ... */);
}
});
Оригинальный ответ
Вы сказали, что PHP stops execution with FATAL ERROR
,
Это неправда. fsockopen
вернет false и выдаст предупреждение (!) в случае ошибки:
// sorry example.com ;)
var_dump(fsockopen("www.example.com", 1000, $errno, $errstr, 3));
Предупреждение PHP: fsockopen(): невозможно подключиться к www.example.com:1000 (истекло время ожидания подключения) в /home/thorsten/src/checkout-plugin/a.php в строке 3 Трассировка стека PHP: PHP 1. {main}() /home/thorsten/src/checkout-plugin/a.php:0 PHP 2. fsockopen() /home/thorsten/src/checkout-plugin/a.php:3 bool(false)
Если вы получаете фатальную ошибку, это может быть вызвано глобальным обработчиком ошибок, который был зарегистрирован с помощью set_error_handler()
и превращает предупреждения в исключения. Некоторые рамки делают это. Если это правда, вы можете использовать оператор "тишины" @
подавить предупреждение:
var_dump(@fsockopen("www.example.com", 1000, $errno, $errstr, 3));
// bool(false)