【辅导】Task15 熟悉错误与异常处理 主要知识点
PHP本来只是面向过程的网络程序设计语言,所以它处理错误(Errors)是完善的。因为加入了面向对象的特性,所以又有了异常(Exceptions),但又与原生的面向对象程序设计语言(如Java, C#)不同,许多错误并不能用异常来处理(一部分原因也因为它是解释型语言,运行前不能排除掉语法错误)。PHP也正努力去改进,让更多的错误可以使用异常来处理,但目前还做不到像Java语言这样。
1、什么是错误?有哪些错误?
在PHP中,错误基本上都可以归纳为程序开发者的代码设计问题,都是应该避免的。因为PHP是解释型语言的原因,所以它要在调试运行阶段显示足够的错误信息,以便于程序员排错。
- 错误,包括Fatal Error和Parse Error:致命错误,会终止其下程序的执行,语法错误的话,PHP压根就没执行。
- 警告,Warning Error:不会终止运行,但会影响结果。
- 注意(或称通知),Notice Error:不会终止执行,也不会影响结果。
在开发阶段,我们希望能够显示所有错误信息,以使于我们排错。但在生产环境,我们不希望显示任何错误信息以扰乱页面的正常显示,但希望错误信息能记录下来,方便程序员在后台排错。
所以就有了开发模式和生产模式两种不同情况下的不同的PHP.ini文件的不同配置,主要就是解决错误显示和错误记录这两个问题。
在PHP.ini配置文件中设置,对站点所有页面文件都有效。除此以外,还可以在页面脚本中使用下面2个函数,来临时改变当前页面的错误设置:
error_reporting()函数和ini_set()函数。
先介绍下error_reporting(int $level)函数:
参数$level是给定错误级别,错误级别在课件中有描述,实际上是用二进位来描述的,比如:
E_ERROR = 0001,E_WARNING = 0010,
E_PARSE = 0100,E_NOTICE = 1000
所以要想所有错误都显示出来,就是4个二进制位都是1,即1111(即15,PHP7中实际上是E_ALL = 32719,15个二进制位,除标记E_STRICT位以外的其它位都为1)。
如果想主要的错误都要显示出来,但几个无关紧要的错误提示不需要显示,那就要在E_ALL的基础上,其中某些二进制位为0,如E_DEPRECATED(过时的)= 8192,即010 0000 0000 0000(第13位为1), 就要通过位运算将E_ALL这个整数的相应位置为0
E_ALL: 111 0111 1111 1111
~E_DEPRECATED: 101 1111 1111 1111
位与运算&: 101 0111 1111 1111
即使用语句:error_reporting( E_ALL & ~ E_DEPRECATED);
也可以:
E_ALL: 111 0111 1111 1111
E_DEPRECATED: 010 0000 0000 0000
异或运算^: 101 0111 1111 1111
即使用语句:error_reporting( E_ALL ^ E_DEPRECATED);
一般不使用:error_reporting(0); 因为这样错误信息不仅不显示,也不报告了(不记录在日志文件中),网站出了问题我们没办法排错了。
所以,我们一般需要报告错误,但可以不显示错误,但需要记录日志,上面的生产环境就是这么设置的,开发模式下一般是要显示错误的,以便于及时发现错误,有时错误太多,某些页面不想显示,就可以用下面语句,临时修改php.ini的某些项的配置:
ini_set('display_errors',0);
当然这个函数也可以在脚本中临时修改其它配置项,脚本结束时配置还原。
2、如何处理错误?
一是使用die()函数,有错误时显示错误信息,停止脚本执行。一般用在建立资源变量的时候,如打开数据库的时候:
$link = mysqli_connect($url, $user, $passwd, $db)
or die("无法连接数据库{$db}!");
二是创建自定义错误处理器。了解set_error_hander()函数的使用。
要注意:自定义错误处理器后,错误信息不会自动记录进日志文件。你可能需要在错误处理函数中自己完成日志文件的读写。
另外,我们也可以使用trigger_error()函数自己触发错误,再按系统定义的方式处理错误,或使用自定义错误处理器处理错误。
3、什么是异常?
一般来说,程序在运行中出现不符合预期的情况,称之为发生异常。但在PHP中,异常需由throw语句抛出(你自己throw,或由你调用的函数throw)。虽然越来越多的PHP系统函数会在有问题时抛出异常,但像数据库连接失败这样的情况(使用mysqli_connect()),仍然还是报错误。
4、如何处理异常?
所有Exception都实现了Throwable接口,所以可以使用catch语句捕捉住Throwable、Exception和部分实现了Throwable接口的Error。
异常处理的规则:
- 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
- try代码块支持嵌套,即try代码块中可以嵌套另一个try代码块。
- try代码块中,要有throw语句抛出异常,或者有实现 了Throwable接口的错误。
- 可以使用多个 catch 代码块,来捕获不同种类的异常。
- 可以在catch 代码块中抛出(再次抛出)异常
- 在try-catch块中,每一个throw语句抛出的异常都要有一个catch块来处理。(否则?就交给set_exception_handler函数设置的顶层异常处理器去处理。如果也没有顶层异常处理器,就抛出Fatal Error:Uncaught Exception错误)
在这里,只需要大家掌握使用try-catch语句来处理异常,课程中介绍的自定义异常类、错误当异常处理、顶层异常处理器set_exception_handler(),只作为扩展知识让大家了解一下。
请大家参考《PHP如何进行错误与异常处理》:
https://www.cnblogs.com/Renyi-Fan/p/10739452.html
5、课程预告
明天(4.23),对Task10 ~Task15的内容进行课堂测验,计入平时成绩。50道题(单选10,多选10,判断10,填空20空),时间从8:30开始,到12:00结束。在线接受大家的咨询(不涉及到试题答案),强调每位同学均需参加测验,否则会影响到课程的成绩的。
下周起(第11周),开始学习PHP操作MySQL。