• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • restore_error_handler()

    (PHP 4 >= 4.0.1, PHP 5, PHP 7)

    还原之前的错误处理函数

    说明

    restore_error_handler(void): bool

    在使用set_error_handler()改变错误处理函数之后,此函数可以用于还原之前的错误处理程序(可以是内置的或者也可以是用户所定义的函数)。

    返回值

    该函数总是返回TRUE

    范例

    Example #1restore_error_handler()范例

    如果是unserialize()导致了一个错误,接下来会恢复原来的错误处理函数。

    <?php
    function unserialize_handler($errno, $errstr)
    {
        echo "Invalid serialized value.\n";
    }
    $serialized = 'foo';
    set_error_handler('unserialize_handler');
    $original = unserialize($serialized);
    restore_error_handler();
    ?>
    

    以上例程会输出:

    Invalid serialized value.
    

    参见

    Isolde is kind of wrong. The error handlers are stacked with set_error_handler(), and popped with restore_error_handler(). Here i put an example:
    <?php
      mysql_connect("inexistent"); //Generate an error. The actual error handler is set by default
      function foo1() {echo "<br>Error foo1<br>";}
      function foo2() {echo "<br>Error foo2<br>";}
      function foo3() {echo "<br>Error foo3<br>";}
      
      set_error_handler("foo1");  //current error handler: foo1
      set_error_handler("foo2");  //current error handler: foo2
      set_error_handler("foo3");  //current error handler: foo3
      
      mysql_connect("inexistent");  
      restore_error_handler();    //now, current error handler: foo2
      mysql_connect("inexistent");   
      restore_error_handler();    //now, current error handler: foo1
      mysql_connect("inexistent"); 
      restore_error_handler();    //now current error handler: default handler
      mysql_connect("inexistent");
      restore_error_handler();    //now current error handler: default handler (The stack can't pop more)
    ?>
    
    Calling restore_error_handler from within an error handler might result in unexpected behaviour:
    <?php
    error_reporting(0);
    set_error_handler('handleError1');
    trigger_error('1-stack:h1');
    set_error_handler('handleError2');
    trigger_error('2-stack:h1,h2');
    trigger_error('6-stack:h1,h2');
    trigger_error('7-stack:h1,h2');
    function handleError1($code, $message, $file = '', $line = 0, $context = array())
    {
      echo __METHOD__ . ' ' . $message . PHP_EOL;
    }
    function handleError2($code, $message, $file = '', $line = 0, $context = array())
    {
      trigger_error('3-DEFAULT'); // This will use the php's default error handler
      echo __METHOD__ . ' ' . $message . PHP_EOL;
      set_error_handler('handleError3');
      trigger_error('4-stack:h1,h2,h3');
      restore_error_handler(); // This will restore the handleError1 instead of the default error handler
      trigger_error('5-DEFAULT');
    }
    function handleError3($code, $message, $file = '', $line = 0, $context = array())
    {
      echo __METHOD__ . ' ' . $message . PHP_EOL;
    }
    ?>
    The above code will output:
    handleError1 1-stack:h1
    handleError2 2-stack:h1,h2
    handleError3 4-stack:h1,h2,h3
    handleError1 5-DEFAULT
    handleError1 6-stack:h1,h2
    handleError1 7-stack:h1,h2
    The following workaround can be used:
    <?php
    error_reporting(0);
    set_error_handler('handleError1');
    trigger_error('1-stack:h1');
    set_error_handler('handleError2');
    trigger_error('2-stack:h1,h2');
    trigger_error('6-stack:h1,h2');
    trigger_error('7-stack:h1,h2');
    function handleError1($code, $message, $file = '', $line = 0, $context = array())
    {
      echo __METHOD__ . ' ' . $message . PHP_EOL;
    }
    function handleError2($code, $message, $file = '', $line = 0, $context = [])
    {
      restore_error_handler(); // This will restore the previous error handler
      set_error_handler('count', 0); // Set a dummy method for error handling, it will never be called because $error_type = 0
      try
      {
        trigger_error('3-DEFAULT');
        echo __METHOD__ . ' ' . $message . PHP_EOL;
        set_error_handler('handleError3');
        trigger_error('4-stack:h1,h2,h3');
        restore_error_handler();
        trigger_error('5-DEFAULT');
      }
      finally
      {
        restore_error_handler(); // Restore the previous error handler
        set_error_handler('handleError2'); // Set the current error handler again
      }
    }
    function handleError3($code, $message, $file = '', $line = 0, $context = [])
    {
      echo __METHOD__ . ' ' . $message . PHP_EOL;
    }
    ?>
    which will output:
    handleError1 1-stack:h1
    handleError2 2-stack:h1,h2
    handleError3 4-stack:h1,h2,h3
    handleError2 6-stack:h1,h2
    handleError3 4-stack:h1,h2,h3
    handleError2 7-stack:h1,h2
    handleError3 4-stack:h1,h2,h3
    Works also for restoring nested error handlers:
    <?php
    error_reporting(E_ALL);
    echo '<pre>';
    set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
      echo 'ErrorHandler 1: ' , $errstr , PHP_EOL;
    });
    trigger_error('Error 1');
    set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
      echo 'ErrorHandler 2: ' , $errstr , PHP_EOL;
    });
    trigger_error('Error 2');
    restore_error_handler();
    trigger_error('Error 3');
    restore_error_handler();
    trigger_error('Error 4');
    ?>
    
    As the docs say, restore_error_handler() revert to the *previous error handler*... even if it is the same. A bug made me set twice my custom error handler and later when I was calling restore_error_handler() to restore the built-in handler nothing seemed to happen... this puzzled me for a while!