찾다
백엔드 개발PHP 튜토리얼拦截PHP各种错误和异常,发生致命异常时进行报警,万事防患于未然

拦截PHP各种异常和错误,发生致命错误时进行报警,万事防患于未然

在日常开发中,大多数人的做法是在开发环境时开启调试模式,在产品环境关闭调试模式。在开发的时候可以查看各种错误、异常,但是在线上就把错误显示的关闭。

上面的情形看似很科学,有人解释为这样很安全,别人看不到错误,以免泄露重要信息...

但是你有没有遇到这种情况,线下好好的,一上线却运行不起来也找不到原因...

一个脚本,跑了好长一段时间,一直没有问题,有一天突然中断了,然后了也没有任何记录都不造啥原因...

线上一个付款,别人明明付了款,但是我们却没有记录到,自己亲自去实验,却是好的...

 

种种以上,都是因为大家关闭了错误信息,并且未将错误、异常记录到日志,导致那些随机发生的错误很难追踪。这样矛盾就来了,即不要显示错误,又要追踪错误,这如何实现了?

以上问题都可以通过PHP的错误、异常机制及其内建函数'set_exception_handler','set_error_handler','register_shutdown_function' 来实现

 

'set_exception_handler' 函数 用于拦截各种未捕获的异常,然后将这些交给用户自定义的方式进行处理

'set_error_handler' 函数可以拦截各种错误,然后交给用户自定义的方式进行处理

'register_shutdown_function' 函数是在PHP脚本结束时调用的函数,配合'error_get_last'可以获取最后的致命性错误

 

这个思路大体就是把错误、异常、致命性错误拦截下来,交给我们自定义的方法进行处理,我们辨别这些错误、异常是否致命,如果是则记录的数据库或者文件系统,然后使用脚本不停的扫描这些日志,发现严重错误立即发送邮件或发送短信进行报警

 

首先我们定义错误拦截类,该类用于将错误、异常拦截下来,用我们自己定义的处理方式进行处理,该类放在文件名为'errorHandler.class.php'中,代码如下

<span style="color: #008000;">/*</span><span style="color: #008000;">* * 文件名称:baseErrorHandler.class.php * 摘    要:错误拦截器父类 </span><span style="color: #008000;">*/</span><span style="color: #0000ff;">require</span> 'errorHandlerException.class.php';<span style="color: #008000;">//</span><span style="color: #008000;">异常类</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> errorHandler{    </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$argvs</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">();    </span><span style="color: #0000ff;">public</span>     <span style="color: #800080;">$memoryReserveSize</span> = 262144;<span style="color: #008000;">//</span><span style="color: #008000;">备用内存大小</span>    <span style="color: #0000ff;">private</span> <span style="color: #800080;">$_memoryReserve</span>;<span style="color: #008000;">//</span><span style="color: #008000;">备用内存</span>    <span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:注册自定义错误、异常拦截器     * 参      数:void     * 返      回:void     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> register()    {        </span><span style="color: #008080;">ini_set</span>('display_errors', 0<span style="color: #000000;">);        </span><span style="color: #008080;">set_exception_handler</span>(<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>, 'handleException'));<span style="color: #008000;">//</span><span style="color: #008000;">截获未捕获的异常</span>        <span style="color: #008080;">set_error_handler</span>(<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>, 'handleError'));<span style="color: #008000;">//</span><span style="color: #008000;">截获各种错误 此处切不可掉换位置        //留下备用内存 供后面拦截致命错误使用</span>        <span style="color: #800080;">$this</span>->memoryReserveSize > 0 && <span style="color: #800080;">$this</span>->_memoryReserve = <span style="color: #008080;">str_repeat</span>('x', <span style="color: #800080;">$this</span>-><span style="color: #000000;">memoryReserveSize);        </span><span style="color: #008080;">register_shutdown_function</span>(<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>, 'handleFatalError'));<span style="color: #008000;">//</span><span style="color: #008000;">截获致命性错误</span><span style="color: #000000;">    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:取消自定义错误、异常拦截器     * 参      数:void     * 返      回:void     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> unregister()    {        </span><span style="color: #008080;">restore_error_handler</span><span style="color: #000000;">();        </span><span style="color: #008080;">restore_exception_handler</span><span style="color: #000000;">();    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:处理截获的未捕获的异常     * 参      数:Exception $exception     * 返      回:void     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> handleException(<span style="color: #800080;">$exception</span><span style="color: #000000;">)    {        </span><span style="color: #800080;">$this</span>-><span style="color: #000000;">unregister();        </span><span style="color: #0000ff;">try</span><span style="color: #000000;">        {            </span><span style="color: #800080;">$this</span>->logException(<span style="color: #800080;">$exception</span><span style="color: #000000;">);            </span><span style="color: #0000ff;">exit</span>(1<span style="color: #000000;">);        }        </span><span style="color: #0000ff;">catch</span>(<span style="color: #0000ff;">Exception</span> <span style="color: #800080;">$e</span><span style="color: #000000;">)        {            </span><span style="color: #0000ff;">exit</span>(1<span style="color: #000000;">);        }    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:处理截获的错误     * 参      数:int     $code 错误代码     * 参      数:string $message 错误信息     * 参      数:string $file 错误文件     * 参      数:int     $line 错误的行数     * 返      回:boolean     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> handleError(<span style="color: #800080;">$code</span>, <span style="color: #800080;">$message</span>, <span style="color: #800080;">$file</span>, <span style="color: #800080;">$line</span><span style="color: #000000;">)    {        </span><span style="color: #008000;">//</span><span style="color: #008000;">该处思想是将错误变成异常抛出 统一交给异常处理函数进行处理</span>        <span style="color: #0000ff;">if</span>((<span style="color: #008080;">error_reporting</span>() & <span style="color: #800080;">$code</span>) && !<span style="color: #008080;">in_array</span>(<span style="color: #800080;">$code</span>, <span style="color: #0000ff;">array</span>(<span style="color: #ff00ff;">E_NOTICE</span>, <span style="color: #ff00ff;">E_WARNING</span>, <span style="color: #ff00ff;">E_USER_NOTICE</span>, <span style="color: #ff00ff;">E_USER_WARNING</span>,<span style="color: #000000;"> E_DEPRECATED)))        {</span><span style="color: #008000;">//</span><span style="color: #008000;">此处只记录严重的错误 对于各种WARNING NOTICE不作处理</span>            <span style="color: #800080;">$exception</span> = <span style="color: #0000ff;">new</span> errorHandlerException(<span style="color: #800080;">$message</span>, <span style="color: #800080;">$code</span>, <span style="color: #800080;">$code</span>, <span style="color: #800080;">$file</span>, <span style="color: #800080;">$line</span><span style="color: #000000;">);            </span><span style="color: #800080;">$trace</span> = <span style="color: #008080;">debug_backtrace</span><span style="color: #000000;">(DEBUG_BACKTRACE_IGNORE_ARGS);            </span><span style="color: #008080;">array_shift</span>(<span style="color: #800080;">$trace</span>);<span style="color: #008000;">//</span><span style="color: #008000;">trace的第一个元素为当前对象 移除</span>            <span style="color: #0000ff;">foreach</span>(<span style="color: #800080;">$trace</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$frame</span><span style="color: #000000;">)             {                </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$frame</span>['function'] == '__toString'<span style="color: #000000;">)                 {</span><span style="color: #008000;">//</span><span style="color: #008000;">如果错误出现在 __toString 方法中 不抛出任何异常</span>                    <span style="color: #800080;">$this</span>->handleException(<span style="color: #800080;">$exception</span><span style="color: #000000;">);                    </span><span style="color: #0000ff;">exit</span>(1<span style="color: #000000;">);                }            }            </span><span style="color: #0000ff;">throw</span> <span style="color: #800080;">$exception</span><span style="color: #000000;">;        }        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:截获致命性错误     * 参      数:void     * 返      回:void     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> handleFatalError()    {        </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->_memoryReserve);<span style="color: #008000;">//</span><span style="color: #008000;">释放内存供下面处理程序使用</span>        <span style="color: #800080;">$error</span> = error_get_last();<span style="color: #008000;">//</span><span style="color: #008000;">最后一条错误信息</span>        <span style="color: #0000ff;">if</span>(errorHandlerException::isFatalError(<span style="color: #800080;">$error</span><span style="color: #000000;">))        {</span><span style="color: #008000;">//</span><span style="color: #008000;">如果是致命错误进行处理</span>            <span style="color: #800080;">$exception</span> = <span style="color: #0000ff;">new</span> errorHandlerException(<span style="color: #800080;">$error</span>['message'], <span style="color: #800080;">$error</span>['type'], <span style="color: #800080;">$error</span>['type'], <span style="color: #800080;">$error</span>['file'], <span style="color: #800080;">$error</span>['line'<span style="color: #000000;">]);            </span><span style="color: #800080;">$this</span>->logException(<span style="color: #800080;">$exception</span><span style="color: #000000;">);            </span><span style="color: #0000ff;">exit</span>(1<span style="color: #000000;">);        }    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:获取服务器IP     * 参      数:void     * 返      回:string     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">final</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getServerIp()    {        </span><span style="color: #800080;">$serverIp</span> = ''<span style="color: #000000;">;        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_SERVER</span>['SERVER_ADDR'<span style="color: #000000;">]))        {            </span><span style="color: #800080;">$serverIp</span> = <span style="color: #800080;">$_SERVER</span>['SERVER_ADDR'<span style="color: #000000;">];        }        </span><span style="color: #0000ff;">elseif</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_SERVER</span>['LOCAL_ADDR'<span style="color: #000000;">]))        {            </span><span style="color: #800080;">$serverIp</span> = <span style="color: #800080;">$_SERVER</span>['LOCAL_ADDR'<span style="color: #000000;">];        }        </span><span style="color: #0000ff;">elseif</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_SERVER</span>['HOSTNAME'<span style="color: #000000;">]))        {            </span><span style="color: #800080;">$serverIp</span> = <span style="color: #008080;">gethostbyname</span>(<span style="color: #800080;">$_SERVER</span>['HOSTNAME'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">else</span><span style="color: #000000;">        {            </span><span style="color: #800080;">$serverIp</span> = <span style="color: #008080;">getenv</span>('SERVER_ADDR'<span style="color: #000000;">);        }                        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$serverIp</span><span style="color: #000000;">;     }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:获取当前URI信息     * 参      数:void     * 返      回:string $url     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getCurrentUri()    {        </span><span style="color: #800080;">$uri</span> = ''<span style="color: #000000;">;        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$_SERVER</span> ["REMOTE_ADDR"<span style="color: #000000;">])        {</span><span style="color: #008000;">//</span><span style="color: #008000;">浏览器浏览模式</span>            <span style="color: #800080;">$uri</span> = 'http://' . <span style="color: #800080;">$_SERVER</span>['SERVER_NAME'] . <span style="color: #800080;">$_SERVER</span>['REQUEST_URI'<span style="color: #000000;">];        }        </span><span style="color: #0000ff;">else</span><span style="color: #000000;">        {</span><span style="color: #008000;">//</span><span style="color: #008000;">命令行模式</span>            <span style="color: #800080;">$params</span> = <span style="color: #800080;">$this</span>-><span style="color: #000000;">argvs;            </span><span style="color: #800080;">$uri</span> = <span style="color: #800080;">$params</span>[0<span style="color: #000000;">];            </span><span style="color: #008080;">array_shift</span>(<span style="color: #800080;">$params</span><span style="color: #000000;">);            </span><span style="color: #0000ff;">for</span>(<span style="color: #800080;">$i</span> = 0, <span style="color: #800080;">$len</span> = <span style="color: #008080;">count</span>(<span style="color: #800080;">$params</span>); <span style="color: #800080;">$i</span> $len; <span style="color: #800080;">$i</span>++<span style="color: #000000;">)            {                </span><span style="color: #800080;">$uri</span> .= ' ' . <span style="color: #800080;">$params</span>[<span style="color: #800080;">$i</span><span style="color: #000000;">];            }        }        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$uri</span><span style="color: #000000;">;    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:记录异常信息     * 参      数:errorHandlerException $e 错误异常     * 返      回:boolean 是否保存成功     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">final</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> logException(<span style="color: #800080;">$e</span><span style="color: #000000;">)    {        </span><span style="color: #800080;">$error</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(                        </span>'add_time'     =>     <span style="color: #008080;">time</span>(),                        'title'     =>     errorHandlerException::getName(<span style="color: #800080;">$e</span>->getCode()),<span style="color: #008000;">//</span><span style="color: #008000;">这里获取用户友好型名称</span>                        'message'     =>     <span style="color: #0000ff;">array</span>(),                        'server_ip' =>     <span style="color: #800080;">$this</span>->getServerIp(),                        'code'         =>     errorHandlerException::getLocalCode(<span style="color: #800080;">$e</span>->getCode()),<span style="color: #008000;">//</span><span style="color: #008000;">这里为各种错误定义一个编号以便查找</span>                        'file'         =>  <span style="color: #800080;">$e</span>->getFile(),                        'line'         =>     <span style="color: #800080;">$e</span>->getLine(),                        'url'        =>  <span style="color: #800080;">$this</span>->getCurrentUri(),<span style="color: #000000;">                    );        </span><span style="color: #0000ff;">do</span><span style="color: #000000;">        {            </span><span style="color: #008000;">//</span><span style="color: #008000;">$e->getFile() . ':' . $e->getLine() . ' ' . $e->getMessage() . '(' . $e->getCode() . ')'</span>            <span style="color: #800080;">$message</span> = (<span style="color: #0000ff;">string</span>)<span style="color: #800080;">$e</span><span style="color: #000000;">;            </span><span style="color: #800080;">$error</span>['message'][] = <span style="color: #800080;">$message</span><span style="color: #000000;">;        } </span><span style="color: #0000ff;">while</span>(<span style="color: #800080;">$e</span> = <span style="color: #800080;">$e</span>-><span style="color: #000000;">getPrevious());        </span><span style="color: #800080;">$error</span>['message'] = <span style="color: #008080;">implode</span>("\r\n", <span style="color: #800080;">$error</span>['message'<span style="color: #000000;">]);        </span><span style="color: #800080;">$this</span>->logError(<span style="color: #800080;">$error</span><span style="color: #000000;">);    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:记录异常信息     * 参      数:array $error = array(     *                                    'time' => int,      *                                    'title' => 'string',      *                                    'message' => 'string',      *                                    'code' => int,     *                                    'server_ip' => 'string'     *                                     'file'     =>  'string',     *                                    'line' => int,     *                                    'url' => 'string',     *                                );     * 返      回:boolean 是否保存成功     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> logError(<span style="color: #800080;">$error</span><span style="color: #000000;">)    {        </span><span style="color: #008000;">/*</span><span style="color: #008000;">这里去实现如何将错误信息记录到日志</span><span style="color: #008000;">*/</span><span style="color: #000000;">    }}</span>

上述代码中,有个'errorHandlerException'类,该类放在文件'errorHandlerException.class.php'中,该类用于将错误转换为异常,以便记录错误发生的文件、行号、错误代码、错误信息等信息,同时其方法'isFatalError'用于辨别该错误是否是致命性错误。这里我们为了方便管理,将错误进行编号并命名。该类的代码如下

<span style="color: #008000;">/*</span><span style="color: #008000;">* * 文件名称:errorHandlerException.class.php * 摘    要:自定义错误异常类 该类继承至PHP内置的错误异常类 </span><span style="color: #008000;">*/</span><span style="color: #0000ff;">class</span> errorHandlerException <span style="color: #0000ff;">extends</span><span style="color: #000000;"> ErrorException{    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$localCode</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(                                        </span><span style="color: #ff00ff;">E_COMPILE_ERROR</span> => 4001,                                        <span style="color: #ff00ff;">E_COMPILE_WARNING</span> => 4002,                                        <span style="color: #ff00ff;">E_CORE_ERROR</span> => 4003,                                        <span style="color: #ff00ff;">E_CORE_WARNING</span> => 4004,<span style="color: #000000;">                                        E_DEPRECATED </span>=> 4005,                                        <span style="color: #ff00ff;">E_ERROR</span> => 4006,                                        <span style="color: #ff00ff;">E_NOTICE</span> => 4007,                                        <span style="color: #ff00ff;">E_PARSE</span> => 4008,<span style="color: #000000;">                                        E_RECOVERABLE_ERROR </span>=> 4009,                                        <span style="color: #ff00ff;">E_STRICT</span> => 4010,<span style="color: #000000;">                                        E_USER_DEPRECATED </span>=> 4011,                                        <span style="color: #ff00ff;">E_USER_ERROR</span> => 4012,                                        <span style="color: #ff00ff;">E_USER_NOTICE</span> => 4013,                                        <span style="color: #ff00ff;">E_USER_WARNING</span> => 4014,                                        <span style="color: #ff00ff;">E_WARNING</span> => 4015,                                        4016 => 4016,<span style="color: #000000;">                                    );    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$localName</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(                                        </span><span style="color: #ff00ff;">E_COMPILE_ERROR</span> => 'PHP Compile Error',                                        <span style="color: #ff00ff;">E_COMPILE_WARNING</span> => 'PHP Compile Warning',                                        <span style="color: #ff00ff;">E_CORE_ERROR</span> => 'PHP Core Error',                                        <span style="color: #ff00ff;">E_CORE_WARNING</span> => 'PHP Core Warning',<span style="color: #000000;">                                        E_DEPRECATED </span>=> 'PHP Deprecated Warning',                                        <span style="color: #ff00ff;">E_ERROR</span> => 'PHP Fatal Error',                                        <span style="color: #ff00ff;">E_NOTICE</span> => 'PHP Notice',                                        <span style="color: #ff00ff;">E_PARSE</span> => 'PHP Parse Error',<span style="color: #000000;">                                        E_RECOVERABLE_ERROR </span>=> 'PHP Recoverable Error',                                        <span style="color: #ff00ff;">E_STRICT</span> => 'PHP Strict Warning',<span style="color: #000000;">                                        E_USER_DEPRECATED </span>=> 'PHP User Deprecated Warning',                                        <span style="color: #ff00ff;">E_USER_ERROR</span> => 'PHP User Error',                                        <span style="color: #ff00ff;">E_USER_NOTICE</span> => 'PHP User Notice',                                        <span style="color: #ff00ff;">E_USER_WARNING</span> => 'PHP User Warning',                                        <span style="color: #ff00ff;">E_WARNING</span> => 'PHP Warning',                                        4016 => 'Customer`s Error',<span style="color: #000000;">                                    );    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:构造函数     * 摘      要:相关知识请查看 http://php.net/manual/en/errorexception.construct.php     *        * 参      数:string        $message     异常信息(可选)     *              int         $code         异常代码(可选)     *              int         $severity     *              string     $filename     异常文件(可选)     *              int         $line         异常的行数(可选)     *           Exception  $previous   上一个异常(可选)     *     * 返      回:void     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$message</span> = '', <span style="color: #800080;">$code</span> = 0, <span style="color: #800080;">$severity</span> = 1, <span style="color: #800080;">$filename</span> = <span style="color: #ff00ff;">__FILE__</span>, <span style="color: #800080;">$line</span> = <span style="color: #ff00ff;">__LINE__</span>, <span style="color: #0000ff;">Exception</span> <span style="color: #800080;">$previous</span> = <span style="color: #0000ff;">null</span><span style="color: #000000;">)    {        parent</span>::__construct(<span style="color: #800080;">$message</span>, <span style="color: #800080;">$code</span>, <span style="color: #800080;">$severity</span>, <span style="color: #800080;">$filename</span>, <span style="color: #800080;">$line</span>, <span style="color: #800080;">$previous</span><span style="color: #000000;">);    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:是否是致命性错误     * 参      数:array $error     * 返      回:boolean     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> isFatalError(<span style="color: #800080;">$error</span><span style="color: #000000;">)    {        </span><span style="color: #800080;">$fatalErrors</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(                                </span><span style="color: #ff00ff;">E_ERROR</span>,                                 <span style="color: #ff00ff;">E_PARSE</span>,                                 <span style="color: #ff00ff;">E_CORE_ERROR</span>,                                <span style="color: #ff00ff;">E_CORE_WARNING</span>,                                 <span style="color: #ff00ff;">E_COMPILE_ERROR</span>,                                 <span style="color: #ff00ff;">E_COMPILE_WARNING</span><span style="color: #000000;">                            );        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$error</span>['type']) && <span style="color: #008080;">in_array</span>(<span style="color: #800080;">$error</span>['type'], <span style="color: #800080;">$fatalErrors</span><span style="color: #000000;">);    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:根据原始的错误代码得到本地的错误代码     * 参      数:int $code     * 返      回:int $localCode     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> getLocalCode(<span style="color: #800080;">$code</span><span style="color: #000000;">)    {        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">isset</span>(self::<span style="color: #800080;">$localCode</span>[<span style="color: #800080;">$code</span>]) ? self::<span style="color: #800080;">$localCode</span>[<span style="color: #800080;">$code</span>] : self::<span style="color: #800080;">$localCode</span>[4016<span style="color: #000000;">];    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:根据原始的错误代码获取用户友好型名称     * 参      数:int      * 返      回:string $name     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> getName(<span style="color: #800080;">$code</span><span style="color: #000000;">)    {        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">isset</span>(self::<span style="color: #800080;">$localName</span>[<span style="color: #800080;">$code</span>]) ? self::<span style="color: #800080;">$localName</span>[<span style="color: #800080;">$code</span>] : self::<span style="color: #800080;">$localName</span>[4016<span style="color: #000000;">];    }</span>

在错误拦截类中,需要用户自己定义实现错误记录的方法('logException'),这个地方需要注意,有些错误可能在一段时间内不断发生,因此只需记录一次即可,你可以使用错误代码、文件、行号、错误详情 生成一个MD5值用于记录该错误是否已经被记录,如果在规定时间内(一个小时)已经被记录过则不需要再进行记录

 

然后我们定义一个文件,用于实例化以上类,捕获各种错误、异常,该文件命名为'registerErrorHandler.php', 内如如下

<span style="color: #008000;">/*</span><span style="color: #008000;">* 使用方法介绍:* 在入口处引入该文件即可,然后可以在该文件中定义调试模式常量'DEBUG_ERROR'** <?php *   *    require 'registerErrorHandler.php';*   * ?></span><span style="color: #008000;">*/</span><span style="color: #008000;">/*</span><span style="color: #008000;">** 调试错误模式:* 0                =>            非调试模式,不显示异常、错误信息但记录异常、错误信息* 1                =>            调试模式,显示异常、错误信息但不记录异常、错误信息</span><span style="color: #008000;">*/</span><span style="color: #008080;">define</span>('DEBUG_ERROR', 0<span style="color: #000000;">);</span><span style="color: #0000ff;">require</span> 'errorHandler.class.php'<span style="color: #000000;">;</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> registerErrorHandler{    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 方      法:注册异常、错误拦截     * 参      数:void     * 返      回:void     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> register()    {        </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">;        </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(DEBUG_ERROR)        {</span><span style="color: #008000;">//</span><span style="color: #008000;">如果开启调试模式</span>            <span style="color: #008080;">ini_set</span>('display_errors', 1<span style="color: #000000;">);            </span><span style="color: #0000ff;">return</span><span style="color: #000000;">;        }        </span><span style="color: #008000;">//</span><span style="color: #008000;">如果不开启调试模式</span>        <span style="color: #008080;">ini_set</span>('error_reporting', -1<span style="color: #000000;">);        </span><span style="color: #008080;">ini_set</span>('display_errors', 0<span style="color: #000000;">);        </span><span style="color: #800080;">$handler</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> errorHandler();        </span><span style="color: #800080;">$handler</span>->argvs = <span style="color: #800080;">$argv</span>;<span style="color: #008000;">//</span><span style="color: #008000;">此处主要兼容命令行模式下获取参数</span>        <span style="color: #800080;">$handler</span>-><span style="color: #000000;">register();    }    }registerErrorHandler</span>::register();

剩下的就是需要你在你的入口文件引入该文件,定义调试模式,然后实现你自己记录错误的方法即可

需要注意的是,有些错误在你进行注册之前已经发生并且导致脚本中断是无法记录下来的,因为此时'registerErrorHandler::register()' 尚未执行已经中断了

还有就是'set_error_handler'这个函数不能捕获下面类型的错误 E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNINGE_COMPILE_ERROR、 E_COMPILE_WARNING, 这个可以在官方文档中看到,但是本处无妨,因为以上错误是解析、编译错误,这些都没有通过,你是不可能发布上线的

 

以上代码经过严格测试,并且已经应用在线上环境,大家可以根据自己需要进行更改使用

 

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP 실행 : 실제 예제 및 응용 프로그램PHP 실행 : 실제 예제 및 응용 프로그램Apr 14, 2025 am 12:19 AM

PHP는 전자 상거래, 컨텐츠 관리 시스템 및 API 개발에 널리 사용됩니다. 1) 전자 상거래 : 쇼핑 카트 기능 및 지불 처리에 사용됩니다. 2) 컨텐츠 관리 시스템 : 동적 컨텐츠 생성 및 사용자 관리에 사용됩니다. 3) API 개발 : 편안한 API 개발 및 API 보안에 사용됩니다. 성능 최적화 및 모범 사례를 통해 PHP 애플리케이션의 효율성과 유지 보수 성이 향상됩니다.

PHP : 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다PHP : 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다Apr 14, 2025 am 12:15 AM

PHP를 사용하면 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다. 1) HTML을 포함하여 컨텐츠를 동적으로 생성하고 사용자 입력 또는 데이터베이스 데이터를 기반으로 실시간으로 표시합니다. 2) 프로세스 양식 제출 및 동적 출력을 생성하여 htmlspecialchars를 사용하여 XSS를 방지합니다. 3) MySQL을 사용하여 사용자 등록 시스템을 작성하고 Password_Hash 및 전처리 명세서를 사용하여 보안을 향상시킵니다. 이러한 기술을 마스터하면 웹 개발의 효율성이 향상됩니다.

PHP 및 Python : 두 가지 인기있는 프로그래밍 언어를 비교합니다PHP 및 Python : 두 가지 인기있는 프로그래밍 언어를 비교합니다Apr 14, 2025 am 12:13 AM

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

PHP의 지속적인 관련성 : 여전히 살아 있습니까?PHP의 지속적인 관련성 : 여전히 살아 있습니까?Apr 14, 2025 am 12:12 AM

PHP는 여전히 역동적이며 현대 프로그래밍 분야에서 여전히 중요한 위치를 차지하고 있습니다. 1) PHP의 단순성과 강력한 커뮤니티 지원으로 인해 웹 개발에 널리 사용됩니다. 2) 유연성과 안정성은 웹 양식, 데이터베이스 작업 및 파일 처리를 처리하는 데 탁월합니다. 3) PHP는 지속적으로 발전하고 최적화하며 초보자 및 숙련 된 개발자에게 적합합니다.

PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오Apr 13, 2025 am 12:20 AM

PHP는 현대 웹 개발, 특히 컨텐츠 관리 및 전자 상거래 플랫폼에서 중요합니다. 1) PHP는 Laravel 및 Symfony와 같은 풍부한 생태계와 강력한 프레임 워크 지원을 가지고 있습니다. 2) Opcache 및 Nginx를 통해 성능 최적화를 달성 할 수 있습니다. 3) PHP8.0은 성능을 향상시키기 위해 JIT 컴파일러를 소개합니다. 4) 클라우드 네이티브 애플리케이션은 Docker 및 Kubernetes를 통해 배포되어 유연성과 확장 성을 향상시킵니다.

PHP 대 기타 언어 : 비교PHP 대 기타 언어 : 비교Apr 13, 2025 am 12:19 AM

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP vs. Python : 핵심 기능 및 기능PHP vs. Python : 핵심 기능 및 기능Apr 13, 2025 am 12:16 AM

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

PHP : 웹 개발의 핵심 언어PHP : 웹 개발의 핵심 언어Apr 13, 2025 am 12:08 AM

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 ​​있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기