How to email PHP Fatal Errors only?

2019-02-04 19:55发布

I am in the middle of refining a rather large bit of code. Alot of it contains many general warnings and notices which do not affect the execution of the code (ie: undefined varilables, or array keys without qoutes).

I want to write a function which allows me to concentrate on the fatal errors first and then I will open it up to the less urgent warnings and notices. I found this code, but it emails every little warning notice and error.

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

How can I modify this code so it only deals with things like:

  • fatal syntax errors
  • undefined functions
  • failure to include files

4条回答
男人必须洒脱
2楼-- · 2019-02-04 20:31

set_error_handler allows you to specify a user-defined error handling function for deciding what to do with certain (but only non-fatal) errors. You can then handle specific types of errors in any fashion you deem necessary, for example notifying a system administrator via email, or saving to a specific log file. See: PHP Doc for further details.

With regards to your request you could the following approach:

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' );

As that error-handling does not work for Fatal Errors (Parse errors, undefined functions etc.), you need to tape this with register_shutdown_function as outlined in a related question:

查看更多
趁早两清
3楼-- · 2019-02-04 20:40

Init following function inside your php file.

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 should be defined on some global location. like function.inc.php. This will send an email to registered user.

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
查看更多
Luminary・发光体
4楼-- · 2019-02-04 20:42

Alerternatively you can use (if you have shell access) a log watcher shell script. This allows to catch any error, including parse errors (which you cannot catch with 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

This is imho more harmless because this is just a side process, and allows you to rely on other technology (shell script or whatever), in case errors happen because of php environment itself, you will still be notified.

查看更多
小情绪 Triste *
5楼-- · 2019-02-04 20:49

Take a look at this

If you where to set your error reporting to something like

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

Then the hope would be that it would pick up the above problems.

查看更多
登录 后发表回答