Block PHP exceptions and errors, alarm when a fatal error occurs, everything is in the bud

Source: Internet
Author: User
Tags deprecated parse error php error
In daily development, most people do this by turning on debug mode in the development environment and turning off debug mode in the product environment. At the time of development, you can look at various errors, exceptions, but on-line to turn off the error display.

The above situation seems very scientific, some people explain that it is safe, others can not see the error, so as not to divulge important information ...

But you have not encountered this situation, the line is good, a line but can not run up and can't find the reason ...

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

Online a payment, others clearly paid, but we did not record, and ourselves to experiment, but is good ...

All of these are due to the fact that the error message has been closed and errors and anomalies have not been logged, which makes it difficult to trace the errors that occur randomly. So the contradiction is coming, that is, do not show errors, but also to track errors, how this is achieved?

The above problems can be achieved by PHP error, anomaly 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 uncaught exceptions and then handle them in a user-defined way

The ' Set_error_handler ' function intercepts various errors and then gives the user a customized way to handle them.

The ' register_shutdown_function ' function is a function called at the end of the php script, with ' error_get_last ' to get the last fatal error

This idea is basically the wrong, abnormal, fatal error interception down, to our custom method for processing, we identify these errors, whether the exception is fatal, if the database or file system is logged, and then use the script to scan these logs, found a serious error immediately send an email or send a text message for the alarm

First we define the error interception class, which is used to intercept errors, exceptions, and handle them in our own defined processing mode, which is placed in the file named ' errorHandler.class.php ', the code is as follows

/** * File name: baseErrorHandler.class.php * Abstract: Error blocker parent class */require ' errorHandlerException.class.php ';//Exception Classes class Errorhandle    r{Public $argvs = Array ();     Public $memoryReserveSize = 262144;//Spare memory size private $_memoryreserve;//spare Memory/** * Method: Register custom error, exception blocker        * Parameter: void * returns: void */Public Function Register () {ini_set (' display_errors ', 0); Set_exception_handler (Array ($this, ' handleexception '));//Intercept uncaught exception Set_error_handler (Array ($this, ' handleError ')); Intercept various errors here must not swap location//leave spare memory for subsequent interception fatal error use $this->memoryreservesize > 0 && $this->_memoryreser        ve = str_repeat (' x ', $this->memoryreservesize);      Register_shutdown_function (Array ($this, ' handlefatalerror '));//Intercept fatal Error}/** * Method: Cancel custom error, exception interceptor * parameter        Number: void * returns: void * * Public function unregister () {Restore_error_handler ();    Restore_exception_handler (); }/** * Method: Handles intercepted uncaught XORConstant * Parameter: 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 $line wrong number of lines * Returned: Boolean */Public function HandleError ($code, $ Message, $file, $line) {//The idea is to turn the error into an exception throw unification to the exception handler function to handle if ((Error_reporting () & $code) &&!i N_array ($code, Array (E_notice, e_warning, E_user_notice, e_user_warning, e_deprecated))) {//Here only serious errors are recorded for various WARNING            Notice not processed $exception = new Errorhandlerexception ($message, $code, $code, $file, $line);            $trace = Debug_backtrace (Debug_backtrace_ignore_args); Array_shift ($trace);//trace.The first element removes a foreach ($trace as $frame) {if ($frame [' function '] = = ' __tostring ') for the current object                    {//If an error occurs in the __tostring method, no exception is thrown $this->handleexception ($exception);                Exit (1);        }} throw $exception;    } return false;        }/** * Method: Interception of fatal error * parameter: void * return: void */Public Function handlefatalerror () { unset ($this->_memoryreserve);//release memory for use by the following handler $error = Error_get_last ();//Last error message if (errorhandlere  Xception::isfatalerror ($error)) {//If a fatal error is processed $exception = new Errorhandlerexception ($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 information * parameter: void * return: string $url */Public Function Getcurrenturi ()        {$uri = '; if ($_server ["REMOTE_ADDR"]) {//browser browse mode $uri = ' http://'. $_server[' server_name ']. $_server[' Request_u        RI '];            } 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: Log Exception information * parameter: errorhandlerexception $e Error Exception * Return: Boolean saved successfully */FINAL                        Public Function Logexception ($e) {$error = array (' add_time ' = = Time (),                        ' Title ' = Errorhandlerexception::getname ($e->getcode ()),//Get a user-friendly name here                        ' message ' = = Array (), ' server_ip ' = $this->getserverip (),                        ' Code ' = Errorhandlerexception::getlocalcode ($e->getcode ()),//This defines a number for various errors to find                        ' 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 * parameter: Array $error = Array (* ' time ' = =  int, * ' title ' = ' String ', * ' message ' = = ' String ', * ' code ' = = int, * ' Ser '                                    Ver_ip ' = ' + ' string ' * ' file ' = ' string ', *                                ' line ' = = int, * ' url ' = ' string ', *     ); * Returns: Whether Boolean is saved successfully */Public function LogError ($error) {/* Here to implement how to log error messages to the journal */}}

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

/** * File name: errorHandlerException.class.php * Abstract: Custom Error Exception class This class inherits from the PHP built-in error exception class */class Errorhandlerexception extends Errore                                        xception{public static $localCode = Array (e_compile_error = 4001, e_compile_warning = 4002, E_core_error = 400 3, e_core_warning = 4004, e_deprecated = > 4005, E_error = 4006, E_notice =&gt ; 4007, E_parse = 4008, E_recoverable_erro R = 4009, e_strict = 4010, E_user_de                                        precated = 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_c                                        Ore_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 recovera                           Ble Error ',             e_strict = ' php STRICT Warning ', e_user_deprecated = ' php USER                                        Deprecated Warning ', E_user_error = ' PHP USER ERROR ', E_user_notice = ' php USER NOTICE ', e_user_warning = ' PHP use R Warning ', e_warning = ' PHP Warning ', 4    016 = ' Customer ' s Error ', ');      /** * Method: Constructor * Summary: Related knowledge please see http://php.net/manual/en/errorexception.construct.php * *         Number: String $message exception information (optional) * int $code exception code (optional) * int     $severity * String $filename exception file (optional) * int $line The number of rows of the exception (optional)   * Exception $previous Previous exception (optional) * * return: void  */Public Function __construct ($message = ", $code = 0, $severity = 1, $filename = __file__, $line = __line__, excep    tion $previous = null) {parent::__construct ($message, $code, $severity, $filename, $line, $previous); }/** * Method: Fatal Error * parameter: Array $error * return: Boolean/public static function Isfat                                 Alerror ($error) {$fatalErrors = Array (E_error,                                 E_parse, E_core_error, e_core_warning,        E_compile_error, e_compile_warning);    return isset ($error [' type ']) && in_array ($error [' type '], $fatalErrors); }/** * Method: Get local error code according to the original error code * parameter: int $code * return: int $localCode */public static function Getlocalcode ($code) {return isset (self:: $localCode [$codE])?    Self:: $localCode [$code]: Self:: $localCode [4016]; }/** * Method: Gets the user-friendly name from the original error code * parameter: Int * Returns: string $name */public static Functio    n GetName ($code) {return isset (self:: $localName [$code])? Self:: $localName [$code]: Self:: $localName [4016]; }

In the error interception class, the user is required to define the method of implementing the Error Record (' Logexception '), this place needs to be aware that some errors may occur over time, so you can only record once, you may 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 it has been recorded within the specified time (one hours)

Then we define a file to instantiate the above class, catch various errors, exceptions, the file is named ' registererrorhandler.php ', as in the following

/** How to use: * Introduce the file at the entrance, then you can define the debug mode constant ' debug_error ' * * 
 
   *//*** Debug Error mode in the file: * 0                =            non-debug mode, do not display exceptions, Error message but log exception, error message * 1                =            Debug mode, display exception, error message but do not log exception, error message */define (' Debug_error ', 0); require ' ErrorHandler.class.php '; class registererrorhandler{    /**     * Square      Method: Registration exception, error intercept     * parameter      : void     * return      back: void     *    /public static function register ()    {        global $argv;        if (debug_error)        {//If you turn on debug mode            ini_set (' display_errors ', 1);            return;        }        If debug mode is not turned on        ini_set (' error_reporting ',-1);        Ini_set (' Display_errors ', 0);        $handler = new ErrorHandler ();        $handler->argvs = $argv;//This is the main compatible command-line mode to get the parameters        $handler->register ();    }    } Registererrorhandler::register ();

All that is left is for you to introduce the file in your portal file, define the debug mode, and then implement your own method of documenting the error.

It is important to note that some errors have occurred before you register and cause the script break to be logged because the ' registererrorhandler::register () ' has not been executed yet.

There is also the ' set_error_handler ' function that does not 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 documentation, but this place is no harm, because the above errors are parsing, compiling errors, these are not passed, you are not likely to publish on-line

The above code has been rigorously tested, and has been applied on-line environment, you can change the use according to their own needs

  • 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.