PHP中的错误:
php中大部分情况是由错误的语法,服务器环境导致,使得编译器无法通过检查,甚至无法运行的情况。warning、notice都是错误,只是他们的级别不同而已,并且错误是不能被try-catch捕获的。
PHP中的异常:
程序在运行中出现不符合预期的情况,允许发生(你也不想让他出现不正常的情况)但他是一种不正常的情况,按照我们的正常逻辑本不该出的错误,但仍然会出现的错误,属于逻辑和业务流程的错误,而不是编译或者语法上的错误。这种我们把他称为异常。
以上是PHP中错误和异常的一个概念,PHP中任何自身的错误或者是非正常的代码都会当做错误对待,并不会以异常的形式抛出,但是也有一些情况会当做异常和错误同时抛出。也就是说,你想在数据库连接失败的时候自动捕获异常是行不通的,因为这就不是异常,是错误。
要做错误处理,必须得明细错误级别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Fatal Error:致命错误(脚本终止运行) E_ERROR // 致命的运行错误,错误无法恢复,暂停执行脚本 E_CORE_ERROR // PHP启动时初始化过程中的致命错误 E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERROR E_USER_ERROR // 自定义错误消息。像用PHP函数trigger_error(错误类型设置为:E_USER_ERROR) Parse Error:编译时解析错误,语法错误(脚本终止运行) E_PARSE //编译时的语法解析错误 Warning Error:警告错误(仅给出提示信息,脚本不终止运行) E_WARNING // 运行时警告 (非致命错误)。 E_CORE_WARNING // PHP初始化启动过程中发生的警告 (非致命错误) 。 E_COMPILE_WARNING // 编译警告 E_USER_WARNING // 用户产生的警告信息 Notice Error:通知错误(仅给出通知信息,脚本不终止运行) E_NOTICE // 运行时通知。表示脚本遇到可能会表现为错误的情况. E_USER_NOTICE // 用户产生的通知信息。
由此可知有5类是产生ERROR级别的错误,这种错误直接导致PHP程序退出。
PHP代码在运行的过程中,一旦出现错误,就会触发系统的错误处理机制。如果我们配置了错误报告就回直接报告出错误。如图所示:
像这样的处理如果我们的代码在生产上运行,就会暴露很多信息(比如服务器的系统),所以我们会做简单的配置:
第一种: 修改php.ini 配置文件:
1 2 3 4 5 error_reporting = E_ALL //将向PHP发送每个错误 display_errors = Off //不显示错误报告 log_errors = On //开启错误日志记录 log_errors_max_log = 1024 //每条日志的最大长度 error_log = G:/myerror.log //指定错误日志文件
注意:由于我们关闭了错误报告,但是错误是存在的,为了排查错误,我们开启了错误日志.
第二种: 不修改配置文件,在代码层处理
1 2 3 4 5 error_reporting (E_ALL); ini_set ('display_errors' ,0 ); ini_set ('log_errors' ,1 ); ini_set ('error_log' ,'./error.log' ); test ();
运行以上代码,就会发现 当前目录下出现 error.log 的文件,内容如下:
1 2 3 4 5 [05-Jul-2018 03:37:38 UTC] PHP Fatal error: Uncaught Error: Call to undefined function test() in D:\phpStudy\WWW\test.php:6 Stack trace: #0 {main} thrown in D:\phpStudy\WWW\test.php on line 6
1 2 3 4 function checkNum ($number ) { return 100 /$number ; }
如上代码所示: 在调用 checkNum()函数的时候 如果在调用的时候 参数传递为0,就会出现异常,这个时候我们就会用到 异常处理操作:
1 2 3 4 5 6 7 function checkNum ($number ) { if ($number ==0 ) { throw new Exception ("参数不能为0" ); } return 100 /$number ; }
然后在调用的时候:
1 2 3 4 5 6 7 8 <?php try { checkNum (2 ); echo '成功了' ; } catch (Exception $e ) { echo '错误信息: ' . $e ->getMessage (); }
再比如如下的异常处理:
1 2 3 <?php $pdo = new PDO ('mysql://host=wrong_host;dbname=wrong_name' );$count = $pdo ->exec ("DELETE FROM fruit WHERE colour = 'red'" );
我们链接数据库执行删除操作的时候,我们无法确保数据库的地址和用户名输入都是正确的时候,就会使用异常处理操作,来优化我们的代码
1 2 3 4 5 6 7 8 9 try { $pdo = new PDO ('mysql://host=wrong_host;dbname=wrong_name' ); $count = $pdo ->exec ("DELETE FROM fruit WHERE colour = 'red'" ); } catch (PDOException $e ) { $code = $e ->getCode (); $message = $e ->getMessage (); echo '对不起,业务正忙,请稍后再试' ; exit ; }
Exception是所有异常的基类。他提供了一下方法给我们用来处理异常:
1 2 3 4 5 6 7 8 9 Exception::getMessage — 获取异常消息内容 Exception::getPrevious — 返回异常链中的前一个异常 Exception::getCode — 获取异常代码 Exception::getFile — 创建异常时的程序文件名称 Exception::getLine — 获取创建的异常所在文件中的行号 Exception::getTrace — 获取异常追踪信息 Exception::getTraceAsString — 获取字符串类型的异常追踪信息 Exception::__toString — 将异常对象转换为字符串 Exception::__clone — 异常克隆