Maison  >  Article  >  développement back-end  >  Comment écrire une exception d'interception PHP

Comment écrire une exception d'interception PHP

(*-*)浩
(*-*)浩original
2019-11-12 14:08:012923parcourir

Les exceptions d'interception PHP peuvent être écrites via les mécanismes d'erreur et d'exception de PHP et ses numéros intégrés 'set_exception_handler', 'set_error_handler' et 'register_shutdown_function'.

Comment écrire une exception d'interception PHP

La fonction 'set_exception_handler' est utilisée pour intercepter diverses exceptions non interceptées, puis les transmettre à celles définies par l'utilisateur. Le 'set_error_handler La fonction '
peut intercepter diverses erreurs puis les transmettre à la méthode de traitement définie par l'utilisateur (apprentissage recommandé :

Tutoriel vidéo PHP

)La fonction 'register_shutdown_function' est une fonction appelée à la fin du script PHP. Avec 'error_get_last', vous pouvez récupérer la dernière erreur fatale

Cette idée De manière générale, les erreurs, exceptions et erreurs fatales sont interceptées. et transmis à nos méthodes personnalisées pour le traitement. Nous identifions si ces erreurs et exceptions sont fatales, si tel est le cas, les enregistrons dans la base de données ou le système de fichiers, puis utilisons des scripts pour analyser en permanence ces erreurs dans le journal, si une erreur grave est détectée. , envoyez immédiatement un e-mail ou un SMS pour signaler l'alarme

Nous définissons d'abord une classe d'interception d'erreurs, qui est utilisée pour intercepter les erreurs et les exceptions et les traiter avec nos propres méthodes de traitement définies. placé dans le fichier nommé 'errorHandler.class.php', et le code est le suivant

/**
 * 文件名称: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 .= &#39; &#39; . $params[$i];
   }
  }
  return $uri;
 }
 /**
  * 方  法:记录异常信息
  * 参  数:errorHandlerException $e 错误异常
  * 返  回:boolean 是否保存成功
  */
 final public function logException($e)
 {
  $error = array(
      &#39;add_time&#39;  =>  time(),
      &#39;title&#39;  =>  errorHandlerException::getName($e->getCode()),//这里获取用户友好型名称
      &#39;message&#39;  =>  array(),
      &#39;server_ip&#39; =>  $this->getServerIp(),
      &#39;code&#39;   =>  errorHandlerException::getLocalCode($e->getCode()),//这里为各种错误定义一个编号以便查找
      &#39;file&#39;   => $e->getFile(),
      &#39;line&#39;   =>  $e->getLine(),
      &#39;url&#39;  => $this->getCurrentUri(),
     );
  do
  {
   //$e->getFile() . &#39;:&#39; . $e->getLine() . &#39; &#39; . $e->getMessage() . &#39;(&#39; . $e->getCode() . &#39;)&#39;
   $message = (string)$e;
   $error[&#39;message&#39;][] = $message;
  } while($e = $e->getPrevious());
  $error[&#39;message&#39;] = implode("\r\n", $error[&#39;message&#39;]);
  $this->logError($error);
 }
 /**
  * 方  法:记录异常信息
  * 参  数:array $error = array(
  *         &#39;time&#39; => int, 
  *         &#39;title&#39; => &#39;string&#39;, 
  *         &#39;message&#39; => &#39;string&#39;, 
  *         &#39;code&#39; => int,
  *         &#39;server_ip&#39; => &#39;string&#39;
  *          &#39;file&#39;  => &#39;string&#39;,
  *         &#39;line&#39; => int,
  *         &#39;url&#39; => &#39;string&#39;,
  *        );
  * 返  回:boolean 是否保存成功
  */
 public function logError($error)
 {
  /*这里去实现如何将错误信息记录到日志*/
 }
}

Dans le code ci-dessus, il y a une classe 'errorHandlerException', qui est placée dans le fichier 'errorHandlerException.class. php', Cette classe est utilisée pour convertir les erreurs en exceptions afin d'enregistrer le fichier, le numéro de ligne, le code d'erreur, le message d'erreur et d'autres informations où l'erreur s'est produite. En même temps, sa méthode 'isFatalError' est utilisée pour identifier si. l'erreur est une erreur fatale.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn