php インターセプト例外は、PHP のエラーおよび例外メカニズムとその組み込み番号 'set_Exception_handler'、'set_error_handler'、および 'register_shutdown_function' を介して書き込むことができます。
'set_Exception_handler' 関数 は、捕捉されなかったさまざまな例外をインターセプトし、それらをユーザー定義のメソッドに渡して処理するために使用されます。
'set_error_handler' 関数 は、さまざまなエラーをインターセプトし、それらをユーザー定義のメソッドに渡して処理できます (推奨学習: PHP ビデオ チュートリアル)
「register_shutdown_function」関数 は、PHP スクリプトの最後に呼び出される関数です。「error_get_last」を使用すると、最後の致命的なエラーを取得できます。一般的に言えば、エラー、例外、および致命的なエラーはインターセプトされ、処理のためにカスタマイズされたメソッドに渡されます。これらのエラーと例外が致命的であるかどうかを識別します。致命的である場合は、それらをデータベースまたはファイル システムに記録し、スクリプトを使用してこれらのエラーを継続的にスキャンします。ログに記録し、重大なエラーが見つかった場合は、すぐに電子メールまたはテキスト メッセージを送信して警告します。
最初に、エラーと例外をインターセプトするために使用されるエラー インターセプト クラスを定義します。このクラスは「errorHandler.class.php」という名前のファイルに配置されており、コードは次のとおりです
/** * 文件名称:baseErrorHandler.class.php * 摘 要:错误拦截器父类 */ require 'errorHandlerException.class.php';//异常类 class errorHandler { public $argvs = array(); public $memoryReserveSize = 262144;//备用内存大小 private $_memoryReserve;//备用内存 /** * 方 法:注册自定义错误、异常拦截器 * 参 数:void * 返 回:void */ public function register() { ini_set('display_errors', 0); set_exception_handler(array($this, 'handleException'));//截获未捕获的异常 set_error_handler(array($this, 'handleError'));//截获各种错误 此处切不可掉换位置 //留下备用内存 供后面拦截致命错误使用 $this->memoryReserveSize > 0 && $this->_memoryReserve = str_repeat('x', $this->memoryReserveSize); register_shutdown_function(array($this, 'handleFatalError'));//截获致命性错误 } /** * 方 法:取消自定义错误、异常拦截器 * 参 数:void * 返 回:void */ public function unregister() { restore_error_handler(); restore_exception_handler(); } /** * 方 法:处理截获的未捕获的异常 * 参 数:Exception $exception * 返 回:void */ public function handleException($exception) { $this->unregister(); try { $this->logException($exception); exit(1); } catch(Exception $e) { exit(1); } } /** * 方 法:处理截获的错误 * 参 数:int $code 错误代码 * 参 数:string $message 错误信息 * 参 数:string $file 错误文件 * 参 数:int $line 错误的行数 * 返 回:boolean */ public function handleError($code, $message, $file, $line) { //该处思想是将错误变成异常抛出 统一交给异常处理函数进行处理 if((error_reporting() & $code) && !in_array($code, array(E_NOTICE, E_WARNING, E_USER_NOTICE, E_USER_WARNING, E_DEPRECATED))) {//此处只记录严重的错误 对于各种WARNING NOTICE不作处理 $exception = new errorHandlerException($message, $code, $code, $file, $line); $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); array_shift($trace);//trace的第一个元素为当前对象 移除 foreach($trace as $frame) { if($frame['function'] == '__toString') {//如果错误出现在 __toString 方法中 不抛出任何异常 $this->handleException($exception); exit(1); } } throw $exception; } return false; } /** * 方 法:截获致命性错误 * 参 数:void * 返 回:void */ public function handleFatalError() { unset($this->_memoryReserve);//释放内存供下面处理程序使用 $error = error_get_last();//最后一条错误信息 if(errorHandlerException::isFatalError($error)) {//如果是致命错误进行处理 $exception = new errorHandlerException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']); $this->logException($exception); exit(1); } } /** * 方 法:获取服务器IP * 参 数:void * 返 回: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; } /** * 方 法:获取当前URI信息 * 参 数:void * 返 回:string $url */ public function getCurrentUri() { $uri = ''; if($_SERVER ["REMOTE_ADDR"]) {//浏览器浏览模式 $uri = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']; } else {//命令行模式 $params = $this->argvs; $uri = $params[0]; array_shift($params); for($i = 0, $len = count($params); $i < $len; $i++) { $uri .= ' ' . $params[$i]; } } return $uri; } /** * 方 法:记录异常信息 * 参 数:errorHandlerException $e 错误异常 * 返 回:boolean 是否保存成功 */ final public function logException($e) { $error = array( 'add_time' => time(), 'title' => errorHandlerException::getName($e->getCode()),//这里获取用户友好型名称 'message' => array(), 'server_ip' => $this->getServerIp(), 'code' => errorHandlerException::getLocalCode($e->getCode()),//这里为各种错误定义一个编号以便查找 '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); } /** * 方 法:记录异常信息 * 参 数:array $error = array( * 'time' => int, * 'title' => 'string', * 'message' => 'string', * 'code' => int, * 'server_ip' => 'string' * 'file' => 'string', * 'line' => int, * 'url' => 'string', * ); * 返 回:boolean 是否保存成功 */ public function logError($error) { /*这里去实现如何将错误信息记录到日志*/ } }上記のコードでは、「errorHandlerException」があります。ファイル「errorHandlerException.class.php」に配置されるクラス、このクラスは、ファイル、行番号、エラー コード、エラー メッセージ、およびエラーが発生したその他の情報を記録するために、エラーを例外に変換するために使用されます。同時に、そのメソッド「isFatalError」を使用して、エラーが致命的なエラーかどうかを識別します。
以上がPHPインターセプト例外の書き方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。