当主机无法访问时,fsockopen会导致致命错误 - "无法连接到"

时间:2014-04-11 13:32:09

标签: php fsockopen

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

1 个答案:

答案 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)