PHP - 生产环境的合理/优雅/优雅错误处理

时间:2013-06-11 05:00:59

标签: php exception exception-handling error-handling

我正在编写一个PHP Web应用程序,它将在不久的将来在生产环境下运行,而不是使用非用户友好的die(),我想我会想出来一个处理ErrorMessages的Class

基本上,我的思维过程是这样的:

  1. 如果Web应用程序处于调试/开发模式,则die()就可以了。

  2. 如果Web应用程序处于生产/实时模式,请不要使用错误消息打扰用户 - 而是尽可能继续,但发送电子邮件给管理员,转储错误消息和任何内容否则我们可以(例如:登录用户,会话详细信息,IP地址,时间等)

  3. 我的(粗略)代码如下:

    <?php
    require_once('config.php');
    
    class ErrorMessage
    {
          private $myErrorDescription;
    
          public function __construct($myErrorDescription)
          {
               $this->myErrorDescription = (string) $myErrorDescription;
    
               if (DEBUG_MODE === true)
                    die($myErrorDescription);
               else
                    $this->sendEmailToAdministrator();
          }
    
          private function sendEmailToAdministrator()
          {
            // Send an e-mail to ERROR_LOGGING_EMAIL_ADDRESS with the description of the problem.
          }
    } 
    
    ?>
    

    Class将用作:

    if (EXPECTED_OUTCOME) {
     // ...
    }
    else {
        new ErrorMessage('Application failed to do XYZ');
    }
    

    这是一种明智的做法还是我在这里重新发明轮子?我知道框架通常有错误处理的解决方案,但我没有使用它(并且不是真的想要)。

    那就是说,我应该使用ExceptionsThrow吗?这种方法的优点/缺点是什么?

1 个答案:

答案 0 :(得分:2)

我建议使用例外。

你可以通过这样做来切换php到发送异常而不是错误:(from PHP ErrorException Page

<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");

/* Trigger exception */
strpos();
?>

然后在遇到错误条件的代码中抛出异常

throw(new Exception("Meaningful Description", "optional error number"));

可以键入异常,这样您就可以派生一个实例,以便可以在catch中定位它

class MyRecoverableException extends Exception {}

然后在您的代码中,您可以包含可能在try / catch块中引发潜在可恢复错误的代码。

 try {
     $res = doSomething();
     if (!$res) throw new MyRecoverableException("Do Somthing Failed");
 } catch(MyRecoverableException $e){
     logError($e);
     showErrorMessage($e->getMessage());
 }

这在数据库事务中非常有用

 try {
      $db->beginTransaction();
      // do a lot of selectes and inserts and stuff
      $db->commit();
 } catch (DBException $e){
      $db->rollback();
      logError($e);
      showErrorMessage("I was unable to do the stuff you asked me too");
 }

启用错误报告后,未捕获的异常将为您提供详细的堆栈跟踪,告诉您抛出异常的位置。

如果关闭错误报告,您将收到500错误。