【问题标题】:How to email PHP Fatal Errors only?如何仅通过电子邮件发送 PHP 致命错误?
【发布时间】:2011-12-09 04:40:17
【问题描述】:

我正在改进大量代码。其中很多包含许多不影响代码执行的一般警告和注意事项(即:未定义的变量,或没有 qoutes 的数组键)。

我想编写一个函数,让我首先专注于致命错误,然后我将打开它以处理不太紧急的警告和通知。我找到了这段代码,但它会通过电子邮件发送每一个小的警告通知和错误。

http://net.tutsplus.com/tutorials/php/quick-tip-email-error-logs-to-yourself-with-php/

如何修改此代码,使其仅处理以下内容:

  • 致命的语法错误
  • 未定义的函数
  • 未能包含文件

【问题讨论】:

    标签: php syntax error-handling


    【解决方案1】:

    set_error_handler 允许您指定用户定义的错误处理函数来决定如何处理某些(但仅限于非致命)错误。然后,您可以以任何您认为必要的方式处理特定类型的错误,例如通过电子邮件通知系统管理员,或保存到特定的日志文件。有关详细信息,请参阅:PHP Doc

    关于您的要求,您可以采用以下方法:

    function myErrorHandler($errno, $errstr, $errfile, $errline)
    {
      if (!(error_reporting() & $errno)) {
        // This error code is not included in error_reporting
        return;
      }
    
      switch ($errno) {
        case E_USER_ERROR:
        case E_ERROR:
        case E_COMPILE_ERROR:
          echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
          echo "  Fatal error on line $errline in file $errfile";
          echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
          echo "Aborting...<br />\n";
          emailErrorFunction($errno,$erstr,$errfile,$errline);
          exit(1);
          break;
    
      default:
          echo "Unknown error type: [$errno] $errstr<br />\n";
          break;
      }
    
    /* Don't execute PHP internal error handler */
      return true;
    }
    // Report all errors
    error_reporting(E_ALL);
    // User a custom error handler to print output
    set_error_handler( 'myErrorHandler' );
    

    由于该错误处理不适用于致命错误(解析错误、未定义函数等),因此您需要将其与register_shutdown_function 一起记录在相关问题中:

    【讨论】:

    • hm...这似乎没有发现未定义的函数或 php 解析错误,例如缺少刹车。
    • 之前可能需要设置error_reporting(E_ALL)。查看我的更新答案。
    【解决方案2】:

    或者,您可以使用(如果您有 shell 访问权限)日志观察程序 shell 脚本。这允许捕获任何错误,包括解析错误(您无法使用 register_shutdown_function 捕获)。

    #!/bin/bash
    tail -f /path_to_error_log/php_error.log|while read LINE;do
    if grep -q "PHP (Parse|Fatal) error" <(echo $LINE); then
    (
    echo "From: server@example.com"
    echo "To: me@example.com"
    echo "Subject: PHP Error"
    echo $LINE
    ) | sendmail -t
    fi
    done
    

    这更无害,因为这只是一个辅助过程,并且允许您依赖其他技术(shell 脚本或其他),以防由于 php 环境本身而发生错误,您仍然会收到通知。

    【讨论】:

      【解决方案3】:

      在您的 php 文件中初始化以下函数。

      register_shutdown_function('mail_on_error'); //inside your php script
      
      /** If  any file having any kind of fatal error, sln team will be notified when cron will
      become fail : following is the name of handler and its type
      E_ERROR: 1 | E_WARNING: 2 | E_PARSE: 4 | E_NOTICE: 8
      */
      
      function mail_on_error() {
          global $objSettings;
      
          $error = error_get_last();
          //print_r($error);    
      
        if ($error['type'] == 1) {
      
              // update file path into db
              $objSettings->update_records($id=1,array('fatal_error' => json_encode($error)));
      
              $exception_in_file_path = __FILE__;
              fatal_error_structure($exception_in_file_path);
      
        }// end if
      
      }// end mail_on_error
      

      fatal_error_structure 应该在某个全局位置定义。喜欢function.inc.php。这将向注册用户发送一封电子邮件。

      function fatal_error_structure($exception_in_file_path){
      
              $subject = "FATAL: Cron Daemon has failed";
      
          sln_send_mail(nl2br("Please check $exception_in_file_path, This cron having FATAL error."), 
              $subject, 'email@address.com',$name_reciever='', 'text/plain');
      
      }// end fatal_error_structure
      

      【讨论】:

      • 这应该被接受,因为它描述了致命错误的处理程序
      【解决方案4】:

      看看this

      如果您将错误报告设置为类似

      error_reporting(E_ERROR | E_PARSE | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR);
      

      那么希望它能够解决上述问题。

      【讨论】:

      • 不,这似乎也不起作用。我认为致命的解析错误阻止了任何错误报告的发生。
      • stackoverflow.com/questions/1142096/fatal-error-php "发生致命错误后无法继续执行脚本 - 这就是致命错误!"
      • 是的,您可以捕获致命错误。你有一次这样做的机会。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 2013-07-29
      • 1970-01-01
      • 2014-09-14
      相关资源
      最近更新 更多