当我将fsockopen调用到无法访问的IP地址时,PHP会停止执行FATAL ERROR,因为它打算这样做。但对我来说这是正常的情况,主机无法访问。有没有办法,如果是致命错误,如何防止停止php,如果是预期的行为?
我不使用任何框架,我自己处理所有错误。我注册这样的处理程序:
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;
}
答案 0 :(得分:5)
问题编辑后的最终答案
您不知道在脚本末尾调用shutdown函数,无论是否发生错误。即使只是一个警告不立即停止脚本,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():无法连接到第3行的/home/thorsten/src/checkout-plugin/a.php中的www.example.com:1000(连接超时) PHP堆栈跟踪: PHP 1. {main}()/home/thorsten/src/checkout-plugin/a.php:0 PHP 2. fsockopen()/home/thorsten/src/checkout-plugin/a.php:3 布尔(假)
如果遇到致命错误,可能是由使用set_error_handler()
注册的全局错误处理程序引起的,并将警告转换为异常。一些框架正在这样做。如果这是真的,你可以使用&#34;沉默&#34; operator @
来禁止警告:
var_dump(@fsockopen("www.example.com", 1000, $errno, $errstr, 3));
// bool(false)