PHP various exceptions and error blocking methods and a fatal error occurred when the alarm _php instance

Source: Internet
Author: User
Tags deprecated parse error php error php script

In daily development, most people's practice is to open debug mode in the development environment and turn off debug mode in the product environment. You can view all kinds of errors and exceptions while you are developing them, but turn off the errors on the line.

The above situation seems very scientific, someone explained that this is very safe, others can not see the error, so as not to divulge important information ...

But have you encountered this kind of situation, the line is good, an on-line but cannot run up also cannot find the reason ...

A script, ran for a long time, has been no problem, one day suddenly interrupted, and then there is no record of what the reason ...

On the line a payment, others clearly paid the money, but we did not record that they personally to the experiment, but is good ...

All of these are due to the fact that people have turned off the error message and have not logged the errors or exceptions to the log, causing the random errors to be difficult to track. So the contradictions come, that is, do not display errors, but also tracking errors, how to achieve it?

All of the above problems can be realized through PHP error, exception mechanism and its built-in function ' Set_exception_handler ', ' set_error_handler ', ' register_shutdown_function '

The ' Set_exception_handler ' function is used to intercept a variety of not-caught exceptions and then handle them in a way that is customized by the user

The ' Set_error_handler ' function can intercept a variety of errors, and then give the user a custom way to handle

The ' register_shutdown_function ' function is a function called at the end of a PHP script, with ' error_get_last ' to get the final fatal error.

The idea is basically to make mistakes, exceptions, fatal errors intercepted, to our custom method for processing, we identify these errors, whether the fatal, if it is a record of the database or file system, and then use the script to keep scanning these logs, find serious errors immediately send mail or send SMS to the police

First we define the error blocking class, which is used to intercept the error, the exception, and handle it in our own defined way, which is placed in the file name ' errorHandler.class.php ' with the code as follows

/** * File name: baseErrorHandler.class.php * Abstract: Error Interceptor Parent/require ' errorHandlerException.class.php '/Exception class class Errorhand
 ler {Public $argvs = array ();  Public $memoryReserveSize = 262144;//Spare memory size private $_memoryreserve;//Standby Memory/** * Method: Registering custom errors, exception interceptor * parameters: void *
  return: void */Public Function Register () {ini_set (' display_errors ', 0); Set_exception_handler (Array ($this, ' handleexception '))//Intercept An unhandled exception Set_error_handler (Array ($this, ' HandleError ')) //intercept all kinds of errors here must not swap position/left spare memory for the back intercept fatal error use $this->memoryreservesize > 0 && $this->_memoryreserve = str_
  Repeat (' x ', $this->memoryreservesize);  Register_shutdown_function (Array ($this, ' handlefatalerror '));/Intercept fatal Error}/** * Method: Canceling custom error, exception interceptor * parameter: void * return
  Back: void */Public function unregister () {Restore_error_handler ();
 Restore_exception_handler ();
 /** * Method: Handling Captured Exception * Parameters: Exception $exception * return: void/Public Function handleexception ($exception) {$this->unregister ();
   try {$this->logexception ($exception);
  Exit (1);
  catch (Exception $e) {exit (1);  /** * Method: Handling intercepted Error * parameter: int $code error code * parameter: String $message error message * parameter: string $file error file * parameter: int Number of rows $line Error * return: Boolean/Public Function HandleError ($code, $message, $file, $line) {//The idea is to turn the error into an exception and give it to the different The normal processing functions are processed if ((Error_reporting () & $code) &&!in_array ($code, Array (E_notice, e_warning, E_user_notice, E_us Er_warning, e_deprecated)) {//Here only serious errors are recorded for various WARNING notice not processed $exception = new Errorhandlerexception ($message, $co
   De, $code, $file, $line);
   $trace = Debug_backtrace (Debug_backtrace_ignore_args); 
    Array_shift ($trace); the first element of//trace removes the foreach ($trace as $frame) {if ($frame [' function '] = = ' __tostring ') for the current object
     {///If the error occurs in the __tostring method without throwing any exceptions $this->handleexception ($exception);
    Exit (1);
  }} throw $exception;
 return false; /** * Method: Intercept fatal error * parameter: VOID * return: void/Public Function handlefatalerror () {unset ($this->_memoryreserve);/free memory for use by the following handler $error = Error_get_last ()///Last error message if (Errorhandlerexception::isfatalerror ($error)) {//If it is a fatal error to process $exception = new Errorha
   Ndlerexception ($error [' message '], $error [' type '], $error [' type '], $error [' file '], $error [' line ']);
   $this->logexception ($exception);
  Exit (1);
  /** * Method: Get server IP * parameter: void * return: String */Final Public Function Getserverip () {$serverIp = ';
  if (Isset ($_server[' server_addr ')) {$serverIp = $_server[' server_addr '];
  } elseif (Isset ($_server[' local_addr ')) {$serverIp = $_server[' local_addr '];
  } elseif (Isset ($_server[' HOSTNAME ')) {$serverIp = gethostbyname ($_server[' HOSTNAME ']);
  else {$serverIp = getenv (' server_addr '); 
 return $serverIp;
  /** * Method: Get current URI info * parameter: void * return: string $url/* Public Function Getcurrenturi () {$uri = '; if ($_server ["REMOTE_addr "]) {//browser browse mode $uri = ' http://'. $_server[' server_name ']. $_server[' Request_uri '];
   else {//command line mode $params = $this->argvs;
   $uri = $params [0];
   Array_shift ($params);
   for ($i = 0, $len = count ($params); $i < $len; $i + +) {$uri. = '. $params [$i];
 } return $uri; /** * Method: Logging Exception information * Parameters: Errorhandlerexception $e Error Exception * Return: Boolean save success/FINAL public function logexcep tion ($e) {$error = array (' Add_time ' => time (), ' title ' => errorhandlerexception::getname ($e   GetCode ()),//Here Gets the user-friendly name ' message ' => array (), ' server_ip ' => $this->getserverip (), ' Code '
      => Errorhandlerexception::getlocalcode ($e->getcode ()),//This defines a number for various errors to find the ' file ' => $e->getfile (),
  ' Line ' => $e->getline (), ' url ' => $this->getcurrenturi (),); do {//$e->getfile (). ':' . $e->getline (). ' ' . $e->getmessage (). ' ('. $e->getcodE ().
   ') ' $message = (string) $e;
  $error [' message '] = $message;
  while ($e = $e->getprevious ());
  $error [' message '] = Implode ("\ r \ n", $error [' message ']);
 $this->logerror ($error); 
  /** * Method: Log Exception information * Parameters: Array $error = Array (* ' time ' => int, * ' title ' => ' string '), * ' Message ' => ' string ', * ' code ' => int, * ' server_ip ' => ' string ' * '
  File ' => ' string ', * ' line ' => int, * ' url ' => ' string ', *); * Return: Boolean Save success/Public function Logerror ($error) {/* * here to implement how to log error messages to logs/}}

In the preceding code, there is a ' errorhandlerexception ' class, which is placed in the file ' errorHandlerException.class.php ', which is used to convert the error to an exception to record the file, line number, error code, Information such as error messages, and its method ' Isfatalerror ' is used to identify whether the error is a fatal error. Here we have the error numbered and named for ease of administration. The code for the class is as follows

/** * File name: errorHandlerException.class.php * Summary: Custom error Exception class This class inherits to PHP's built-in error exception class/class Errorhandlerexception extends Erro rexception {public static $localCode = Array (e_compile_error => 4001, e_compile_warning => 40 E_core_error => 4003, e_core_warning => 4004, e_deprecated => 4005, E
          _error => 4006, E_notice => 4007, E_parse => 4008, E_recoverable_error => 4009, E_strict => 4010, e_user_deprecated => 4011, E_user_error => 4012, E_user
         _notice => 4013, e_user_warning => 4014, e_warning => 4015, 4016 => 4016,
 ); public static $localName = Array (e_compile_error => ' PHP COMPILE ERROR ', e_compile_warning => '
          PHP Compile Warning ', E_core_error => ' php core ERROR ', e_core_warning => ' php core Warning ', E_deprecaTED => ' php deprecated Warning ', e_error => ' php Fatal ERROR ', E_notice => ' php NOTICE ', E_parse => ' php PARSE error ', E_recoverable_error => ' php recoverable error ', E_strict =&G T ' PHP Strict Warning ', e_user_deprecated => ' php USER deprecated Warning ', e_user_error => ' php U
          Ser Error ', e_user_notice => ' php user NOTICE ', e_user_warning => ' php user WARNING ',
 E_warning => ' PHP WARNING ', 4016 => ' Customer ' s Error ',); /** * Method: Constructor * Summary: Related knowledge please see http://php.net/manual/en/errorexception.construct.php * * Parameters: String $message different Constant information (optional) * int $code exception code (optional) * int $severity * String $filename exception file (optional) * int $line number of rows of an exception (optional) * Exception $previous Previous exception (optional) * * return: void/Public Function __construct ($message = ', $code = 0, $se Verity = 1, $filename = __file__, $line = __line__, ExceptIon $previous = null) {parent::__construct ($message, $code, $severity, $filename, $line, $previous); /** * Method: Is fatal error * parameter: Array $error * return: Boolean/public static function Isfatalerror ($error) {$FA talerrors = Array (e_error, E_parse, E_core_error, e_core_warning, E_compile_er
  ROR, e_compile_warning);
 return isset ($error [' type ']) && in_array ($error [' type '], $fatalErrors); /** * Method: A local error code * parameter based on the original error code: INT $code * returns: int $localCode */public static function Getlocalcode ($c
 Ode) {return isset (self:: $localCode [$code])? Self:: $localCode [$code]: Self:: $localCode [4016]; /** * Method: Gets the user-friendly name * parameter based on the original error code: INT * Returns: string $name/*/public static function GetName ($code) {RE Turn isset (self:: $localName [$code])?
 Self:: $localName [$code]: Self:: $localName [4016]; }

In the error blocking class, the user is required to define the method of implementing the Error Record (' Logexception '), where it is necessary to note that some errors may occur over time, so you can use the error code, file, line number, error details Generates a MD5 value that records whether the error has been recorded and does not need to be recorded if (one hours) has been recorded within a specified time period

Then we define a file that instantiates the above classes, catches various errors, exceptions, which are named ' registererrorhandler.php ', as follows

*
* Use method Introduction:
* Introduce the file at the entrance, then you can define the debug mode constant ' Debug_error '
* <?php * 
require ' in the file Registererrorhandler.php ';
* 
*?>
/
/**
* Debug Error mode:
* 0    =>   debug mode, do not display exception, error message but log exception, error message
* 1    = >   debug mode, display exception, error message but not log exception, error message
* *
define (' Debug_error ', 0);
Require ' errorHandler.class.php ';
Class Registererrorhandler
{
 /**
  * Square  Method: Registration exception, error blocking
  * parameters  : void
  * return  : void
  *
 /public static function register ()
 {
  global $argv;
  if (debug_error)
  {//If debug mode
   is turned on ini_set (' Display_errors ', 1);
   return;
  }
  If the debug mode is not turned
  on Ini_set (' error_reporting ',-1);
  Ini_set (' Display_errors ', 0);
  $handler = new ErrorHandler ();
  $handler->argvs = $argv//$handler Get the parameters in the main compatibility command line mode
  ->register ()
 ; 

All that's left is for you to introduce the file into your entry file, define the debug mode, and then implement your own way of recording the error.

It should be noted that some errors have occurred before you registered and that the script interrupt was not recorded because the ' Registererrorhandler::register () ' has not been executed yet.

There is also the ' set_error_handler ' This function cannot capture the following types of errors E_error, E_parse, E_core_error, e_core_warning, E_compile_error, E_compile _warning, this can be seen in the official document, but there is no harm in this, because the above error is parse, compile error, these are not passed, you are not able to publish the online

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.