php - 当主机无法访问时,fsockopen 会导致 fatal error - "unable to connect to"

标签 php fsockopen

当我调用 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;
}

最佳答案

问题编辑后的最终答案

您不知道无论是否发生错误,都会在脚本末尾调用 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 因 fatal error 而停止执行

这不是真的。如果出现错误,fsockopen 将返回 false 并抛出警告(!):

// sorry example.com ;)
var_dump(fsockopen("www.example.com", 1000, $errno, $errstr, 3));

PHP Warning: fsockopen(): unable to connect to www.example.com:1000 (Connection timed out) in /home/thorsten/src/checkout-plugin/a.php on line 3 PHP Stack trace: PHP 1. {main}() /home/thorsten/src/checkout-plugin/a.php:0 PHP 2. fsockopen() /home/thorsten/src/checkout-plugin/a.php:3 bool(false)

如果遇到 fatal error ,这可能是由使用 set_error_handler() 注册的全局错误处理程序引起的,并将警告转换为异常。一些框架正在这样做。如果这是真的,您可以使用“沉默”运算符@来抑制警告:

var_dump(@fsockopen("www.example.com", 1000, $errno, $errstr, 3));
// bool(false)

关于php - 当主机无法访问时,fsockopen 会导致 fatal error - "unable to connect to",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23014090/

相关文章:

php - 打印时 IE 不重新发送 cookie

php - 从实体对象 symfony 2 调用学说

php - 从包含重复元素的 XML 转换 PHP 数组

php - fwrite 返回(资源暂时不可用)

php - 如何异步运行多个 fsockopen()

php - 将 fsockopen 与代理一起使用

php - mysql 查询在函数中使用时不起作用

php - 在PHP循环中建立逗号分隔的字符串

php - 如何修复 fsockopen 错误?