代码学堂(uxuew.cn)提供付费解决PHP WEB开发等技术服务,如果需要请 点击加我QQ:1662935793.
>编程开发 > php教程 > php异常及错误信息捕获并记录日志实现方法全解析

php异常及错误信息捕获并记录日志实现方法全解析

php教程 围观3400次 更新日期:2017-07-12 14:56:33 留下足迹

一、php异常处理


 什么是异常?

PHP 5 提供了一种新的面向对象的错误处理方法。
异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。

当异常被触发时,通常会发生:

  1、当前代码状态被保存
  
2、代码执行被切换到预定义的异常处理器函数
  3、根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本

当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。

     
如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息。


php系统自带异常处理:Exception

  1.  
  2. header("Content-type:text/html;charset=utf-8"); 
  3. try 
  4. {
  5.     //业务处理 错误时抛出异常。 
  6.     $age = 130; 
  7.     if ($age > 120) { 
  8.         throw new Exception('代码学堂www.uxuew.cn。',888); 
  9.     } 
  10. }catch (Exception $e) { 
  11.     $err = [ 
  12.         'code' => $e->getCode(), 
  13.         'msg'  => $e->getMessage(), 
  14.         'file'    => $e->getFile(), 
  15.         'line'   => $e->getLine() 
  16.     ]; 
  17.     echo json_encode($err); 
  18. }
  19. //输出:{"code":888,"msg":"\u5e74\u9f84\u4e0d\u80fd\u5927\u4e8e120\u5c81\u3002","file":"\/ceshi.php","line":11} 

php自定义异常处理:

  1. header("Content-type:text/html;charset=utf-8"); 
  2. class proException extends Exception 
  3.     //根据业务需求,自定义方法 
  4.     /** 
  5.      * 获取错误信息 
  6.      * @param int $type 类型 1=json 2=数组 
  7.      * @return array 
  8.      */ 
  9.     public function getErrorInfo($type = 2) 
  10.     { 
  11.         $err = [ 
  12.             'code' => $this->getCode(), 
  13.             'msg'  => $this->getMessage(), 
  14.             'file'    => $this->getFile(), 
  15.             'line'   => $this->getLine() 
  16.         ]; 
  17.         if ($type == 1) { 
  18.             return json_encode($err); 
  19.         } 
  20.         return $err
  21.     } 
  22.  
  23. try 
  24.     //业务处理 错误时抛出异常。 
  25.     $site =$_SERVER['HTTP_HOST'] ; 
  26.     if ($site == 'www.uxuew.cn') { 
  27.         throw new proException('代码学堂官网',999); 
  28.     } 
  29. } catch (proException $e) { 
  30.     $info = $e->getErrorInfo(); 
  31.     var_dump($info); 
  32.  
  33. 输出:array(4){["code"]=>int(999) ["msg"]=>string(27)"代码学堂官网" ["file"]=>string(17) "/ceshi.php" ["line"]=>int(53)} 

php还可以捕捉多个异常

  1. header("Content-type:text/html;charset=utf-8"); 
  2. class proException extends Exception 
  3.     //根据业务需求,自定义错误方法 
  4.     /** 
  5.      * 获取错误信息 
  6.      * @param int $type 类型 1=json 2=数组 
  7.      * @return array 
  8.      */ 
  9.     public function getErrorInfo($type = 2) 
  10.     { 
  11.         $err = [ 
  12.             'code' => $this->getCode(), 
  13.             'msg'  => $this->getMessage(), 
  14.             'file'    => $this->getFile(), 
  15.             'line'   => $this->getLine() 
  16.         ]; 
  17.         if ($type == 1) { 
  18.             return json_encode($err); 
  19.         } 
  20.         return $err
  21.     } 
  22.  
  23. try 
  24.     if ($_GET['age'] > 100) { 
  25.         throw new proException('自定义的异常处理', 1002); 
  26.     } else { 
  27.         throw new Exception('系统的异常处理', 1002); 
  28.     } 
  29. } catch (proException $e) { 
  30.     $info =  $e->getErrorInfo(); 
  31.     var_dump($info);//自定义异常处理 
  32. } catch (Exception $e) { 
  33.     echo $e->getMessage();//系统异常处理 

设置顶层异常处理器 (Top Level Exception Handler)

set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数
 

  1. function myException($exception
  2. echo "Exception: " , $exception->getMessage(); 
  3.  
  4. set_exception_handler('myException'); 
  5. throw new Exception('Uncaught Exception occurred'); 
  6. ?> 
在上面的代码中,不存在 "catch" 代码块,而是触发顶层的异常处理程序。应该使用此函数来捕获所有未被捕获的异常。

二、php错误处理


      在创建脚本和 web 应用程序时,错误处理是一个重要的部分。如果您的代码缺少错误检测编码,那么程序看上去很不专业,也为安全风险敞开了大门。

      如果在本地程序调试时出现系统致命性错误可以设置error_reporting(E_ALL)来显示所有错误信息,但在服务器中我们是不能这样做的,这样很容易暴露系统信息,那么我们要如何处理系统错误呢

1、我们可以自定义系统报错函数:

set_error_handler('errorHandler',E_ALL | E_STRICT //设置错误处理器函数errorHandler,可以配合error_log函数实现日志记录功能

参数:
   errorhandler 必需。规定用户错误处理函数的名称。
  E_ALL|E_STRICT 可选。规定显示何种错误报告级别的用户定义错误。默认是 "E_ALL"。


注:
        E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不会被这个句柄处理的,也就是会用最原始的方式显示出来。不过出现这些错误都是编译或PHP内核出错,在通常情况下不会发生

       使用set_error_handler()后,error_reporting()将会失效。也就是所有的错误(除上述的错误)都会交给自定义的函数处理。  


2、捕获系统致命性错误

error_get_last() //获取最后一次发生错误信息;
register_shutdown_function('fatalErrorHandler') //在脚本停止执行时注册一个回调函数


注:通过以上两个函数我们用可以监控系统致命性错误,比如服务器500错误,然后并记录到日志文件中

代码实例:

  1. //禁止错误输出 
  2. error_reporting(0); 
  3. //设置错误处理器 
  4. set_error_handler('errorHandler'); 
  5. //在脚本结束时运行的函数 
  6. register_shutdown_function('fatalErrorHandler'); 
  7.  
  8. /** 
  9. * 错误处理 
  10. * @param int    $err_no      错误代码 
  11. * @param string $err_msg  错误信息 
  12. * @param string $err_file    错误文件 
  13. * @param int    $err_line     错误行号 
  14. * @return string 
  15. */ 
  16. function errorHandler($err_no = 0, $err_msg = ''$err_file = ''$err_line = 0) 
  17.     $log = [ 
  18.         '['.date('Y-m-d h-i-s').']'
  19.         '|'
  20.         $err_no
  21.         '|'
  22.         $err_msg
  23.         '|'
  24.         $err_file
  25.         '|'
  26.         $err_line 
  27.     ]; 
  28.     $log_path = '/data/mi/test.txt'
  29.     error_log(implode(' ',$log)."\r\n",3, $log_path); 
  30.     //echo implode(' ',$log).""; 
  31.  
  32. /** 
  33. * 捕捉致命错误 
  34. * @return string 
  35. */ 
  36. function fatalErrorHandler() { 
  37.     $e = error_get_last(); 
  38.     switch ($e['type']) { 
  39.         case 1: 
  40.             errorHandler($e['type'], $e['message'], $e['file'], $e['line']); 
  41.             break
  42.     } 
  43.  
  44. class DemoClass_1 
  45.     public function index() 
  46.     { 
  47.         //这里发生一个警告错误,出发errorHandler 
  48.         echo $undefinedVarible
  49.     } 
  50.  
  51. $demo_1 = new DemoClass_1(); 
  52. //这里发生一个警告错误,被errorHandler 捕获 
  53. $demo_1->index(); 
  54. //发生致命错误,脚本停止运行触发 fatalErrorHandler 
  55. $demo_2 = new DemoClass_2(); 
  56. $demo_2->index(); 

打开echo后 输出:

[2016-08-07 09-01-34] | 8 | Undefined variable: undefinedVarible | /data/mi/demo.php | 126

[2016-08-07 09-01-34] | 1 | Class 'DemoClass_2' not found | /data/mi/demo.php | 134


备注:

1. register_shutdown_function 也可以用于API调试中,记录每次请求值和返回值,方便调试。

2. 利用 “|” 分割的好处是,便于利用 awk 对日志进行分割处理。


转载请注明:代码学堂>编程开发 > php教程 > php异常及错误信息捕获并记录日志实现方法全解析

喜欢 (884) or 分享 (162)