PHP从入门到精通—错误与异常处理—错误处理、异常处理、调试方法
学习对面向对象(PHP从入门到精通—面向对象—面向对象的概念、类与对象、继承、魔术方法、设计模式)有一个基本的了解,下面进行了解PHP编程错误与异常处理的基础知识,包括错误处理、异常处理的概念、异常处理实现和自定义异常、调试方法。 错误处理 初学者在编程时,经常会遇到各种错误,这时就需要根据不同的错误类型进行处理,正确的错误处理方法可以提高开发效率。 ? 错误类型 错误是指在开发阶段中由一些失误引起的程序问题,根据其出现在编程过程中的不同环节,大致可以分为三类,具体如下所示: 1.语法错误 语法错误是指编写的程序中出现了不符合PHP语法规范的代码,例如,关键字拼写出现错误,这时执行PHP脚本,就会显示错误信息。这类错误通常发生在程序编写时,可以通过错误报告进行修复。 2.逻辑错误 逻辑错误是指在程序中使用的逻辑与实际需要的逻辑不符,例如,在if语句中判断两个变量是否恒等,如果把运算符“===”写成“==”就会出现逻辑错误。这种错误有时不容易被发现,因为它不会阻止PHP脚本的执行,也不会显示错误信息。 3.运行错误 运行错误是指PHP本身以外的因素所造成的错误,例如,操作文件时没有相应的权限。运行错误与程序代码无关。 ? 错误级别 PHP中每个错误都有一个错误级别与之对应,如表所示。 级别 说明 E_ALL 所有错误和警告信息 E_ERROR 致命的运行时错误(它会阻止脚本运行) E_WARNING 运行时警告(非致命的错误) E_PARSE 编译时语法解析错误 E_NOTICE 运行时通知,表示脚本遇到可能会表现为错误的情况 E_STRICT 启用 PHP 对代码的修改建议 E_CORE_ERROR PHP初始启动期间发生的致命错误 E_CORE_WARNING PHP初始启动期间出现的警告(非致命的错误) E_COMPILE_ERROR 编译时致命错误 E_COMPILE_WARNING 编译时警告(非致命错误) E_USER_ERROR 用户产生的错误信息 E_USER_WARNING 用户产生的警告信息 E_USER_NOTICE 用户产生的通知信息 在表中,每个错误级别常量都是一个整数,此处并没有列出其值,使用时可以通过按位运算符来组合这些常量,用来表示某些类型的错误。 ? 显示错误报告 用户在开发程序时,有时希望可以控制是否显示错误以及显示错误的级别。为此,PHP提供了两种方法来显示错误报告,如下所示。 1.修改配置文件 在配置文件php.ini(注意WampServer集成开发环境中需要修改D:\wamp64\bin\apache\apache2.4.27\bin\php.ini文件)中修改配置指令error_reporting的值,修改完成后重新启动Web服务器,具体示例如下: error_reporting(E_All & ~E_NOTICE); display_errors=on; 其中,第1行error_reporting用于设置错误级别,“E_All & ~E_NOTICE”表示显示除E_NOTICE外的所有级别的错误,即显示任何非通知的错误;第2行用于设置是否显示错误报告,on表示显示,off表示不显示。 2.ini_set()和error_reporting()函数 显示报告还可以通过在PHP脚本中使用ini_set()和error_reporting()函数来实现。 ini_set()函数可以为一个配置选项设置值,其语法格式如下: string ini_set(string $varname, string $newvalue) 注意这个选项会在脚本运行时保持新的值,并在脚本结束时恢复。 error_reporting()函数用于确定PHP应该在特定的页面内报告哪些类型的错误,其语法格式如下: int error_reporting([int $level]) 该函数能够在运行时设置error_reporting指令,$level表示报告错误级别。 ? 记录错误日志 不管是何种类型的错误,默认情况下,PHP都会给出提示信息。在实际Web环境中,浏览器将这些信息显示出来,一方面造成极差的用户体验,另一方面会给服务器带来安全隐患,例如错误信息一般包含文件路径信息,黑客据此可以发起攻击。为了解决这一问题,开发者可以在单独的文本文件中将错误报告作为日志记录。在PHP中可以通过两种方式来记录错误日志,具体如下所示。 1.修改配置文件 在PHP配置文件php.ini中,用户可以设置记录错误日志的相关信息,具体如下所示: 其中,error_reporting用于设置显示错误级别,E_ALL表示显示所有错误报告;display_errors用于设置是否显示错误报告,off表示不显示;log_errors用于设置是否记录日志,On表示记录;error_log用于指定产生的错误报告写入日志文件的位置,D:/wamp64/logs/php_error.log表示日志文件路径。 配置文件php.ini按上述方式配置完成后,重新启动Web服务器,当执行PHP脚本文件时,产生的错误报告都不会显示在浏览器中,而是记录在D:/wamp64/logs/php_error.log文件中。 2.error_log()函数 error_log()函数也可以记录错误日志,其语法格式如下: 该函数表示发送错误信息到某个地方,$message表示需要记录的错误信息,$message_type设置错误应该发送到何处,其取值如表所示。 取值 说明 0 $message发送到操作系统日志或文件,取决于error_log指令设置的值 1 $message发送到$destination设置的邮件地址,$extra_headers只有在此处会用到 2 不再是一个选项 3 $message被发送到位置为$destination的文件里 4 直接发送到 SAPI 的日志处理程序中 error_log()函数的用法,如下所示: 其中,第1行代码表示将错误信息发送到操作系统日志或文件中,第2行表示将错误信息发送到xiaoqian@1000phone.com(注意默认条件下是不能发送成功的,需要配置邮件服务器信息),第3行表示将错误信息发送到当前目录下error.log文件中。 ? 自定义错误处理 前面学习的错误处理都是由标准PHP处理函数完成,有时为了更好地处理错误,用户需要自定义错误处理方式。set_error_handler()函数用于设置一个用户定义的错误处理函数,其语法格式如下: 其中,$error_handler是一个回调函数(发生错误时运行的函数),$error_types用于指定错误级别类型。 另外,$error_handler函数的参数必须符合如下格式: 函数的每个参数含义如表所示。 参数 说明 $errno 错误的级别 $errstr 错误的信息 $errfile 发生错误的文件名 $errline 错误发生的行号 $errcontext 错误触发处作用域内所有变量的数组 异常处理 ? 异常处理的概念 异常处理是对产生未知错误所采取的处理措施,它将错误处理的控制流从正常运行的控制流中分离开。异常处理使编程者不用再绞尽脑汁去考虑各种错误,为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。 异常处理可以实现一种另类的条件选择语句,其语法格式如下: 其中,try语句块中为可能出现异常的代码,当有异常发生时,可以通过throw语句抛出一个异常对象,catch语句块可以捕获异常并进行处理。如果在try语句块中有异常对象被抛出,则该语句块不会再继续往下执行,而是直接跳转到catch处捕获异常。这个过程类似于棒球比赛中投手抛出球,球被捕手捕获,如图6.6所示。 由于这种异常处理机制使得异常的抛出与处理不在同一个模块中,因此引发异常模块可以着重解决具体问题,而不必过多地考虑对异常的处理,异常处理模块可以在适当的位置设计对异常的处理,这在大型程序中是非常有必要的。 catch后面括号中的Execption为异常类,用于描述异常信息,其定义如下所示: Exception是所有异常的基类,其成员属性与成员方法都是用来记录和获取程序中的异常信息。 ? 异常处理实现 异常处理可以通过try-catch语句实现,使用时需注意以下几点: l 如果try语句块未抛出任何异常,try语句块将运行完毕,catch语句块内容不会被执行。 l 如果 try语句块抛出了异常,程序会立刻在catch语句块中寻找可以捕获该异常的catch语句块,并运行相应的catch语句块代码,然后跳出try-catch语句块继续运行。 l 如果try语句块中的异常不能被catch语句块捕获,异常将会向上层(如果有)抛出,或者程序终止运行。 l 在catch语句块中,异常类型后面跟的是一个变量,这个变量将指向被捕获的异常实例对象。 当从一个数组中取值,未使用异常处理时,如果访问数组越界,PHP只会报告一个通知错误,用户无法对这个错误做任何处理。 ? 自定义异常 虽然PHP内置的异常类Exception可以记录和获取程序中的异常,但有时用户希望针对特定类型的异常采用自定义的异常类来处理。注意自定义的异常类必须继承自 Exception类或者其子类。 ? 多个异常 对于抛出多个异常,程序可以通过以下两种方式进行处理: 1.一个catch语句块处理多种异常 catch语句块可以捕获在其后声明的异常类和其子类的实例对象,如例所示。 1 在例中,第10~17行为try语句块,当$pwd中字符全为字母时,抛出MyException异常;当$pwd中字符全为数字时,抛出Exception异常。第17行一个catch语句块既可以捕获第12行的异常,也可以捕获第15行的异常,实现了一个异常处理块捕获多种异常。 2.多个catch语句块处理多种异常 除了上述方法外,一个try语句块还可以跟随多个catch语句块,每个catch语句块捕获不同的异常,如例所示。 1 在例中,第17~21行使用了两个catch语句块来处理try语句块中抛出的异常。当有异常被抛出,程序从catch语句块中寻找能处理这个异常的catch语句块。 ? 重抛异常 程序一旦抛出一个异常对象,便会寻找能够处理当前异常的try-catch语句块。如果当前的catch语句块不能够处理这个异常,该异常就会向外重新抛出,如例所示。 在例中,第7行抛出Exception异常,此处try语句块对应的catch语句块不能捕获Exception异常,因此该异常需要重新抛出到外层try-catch语句块中,最终该异常被12行的catch语句块捕捉并处理。此处需注意,如果异常抛到最外层都无法处理这个异常,那么会引发致命错误。 程序一旦抛出一个异常对象,便会寻找能够处理当前异常的try-catch语句块。如果当前的catch语句块不能够处理这个异常,该异常就会向外重新抛出。 此处需注意,如果异常抛到最外层都无法处理这个异常,那么会引发致命错误。 ? 自定义异常处理 当程序中抛出异常时,如果没有相应的异常捕获,就会引发致命错误。为了保证程序的正确运行,可以增加try-catch语句块,但程序中出现的异常有时是无法预料的,这时可以通过set_exception_handler()函数来自定义异常处理,其语法格式如下: 其中,$exception_handler表示当一个未通过catch捕获的异常发生时所调用函数的名称。该函数返回之前所调用函数的名称,或者在错误时返回null。 调试方法 程序开发者会不可避免地遇到各种各样的错误,此时就需要对程序进行调试。通过调试,开发者可以很快找到错误并解决,从而提高开发效率。 ? 使用输出语句进行调试 在PHP中,使用输出语句进行调试是最简单、最直观的一种方法。这种方法可以根据需求查看中间变量的值,适用于程序没有语法错误,但由于某种原因最终得不到预期效果。 常见的输出语句有echo、print_r()函数、var_dump()函数。 ? 使用文件记录进行调试 除了使用输出语句将调试信息输出外,程序中还可以使用文件记录调试信息。file_put_contents()函数可以将调试信息记录到指定文件,其语法格式如下: 其中,$filename表示被写入记录的文件名,$data表示需要写入的信息。后两个参数暂时不用理解,后续章节会再次说明。 ? 使用Xdebug进行调试 Xdebug是一个开放源代码的PHP程序调试器,可以用来跟踪、调试和分析PHP程序的运行状况。WampServer集成开发环境中默认安装了Xdebug模块,如果需要开启Xdebug功能,则在php.ini文件中配置Xdebug选项,具体如下所示: 第3行设置正确的动态链接库(注意动态链接库文件路径与文件名需正确)。修改完配置文件后,重启服务器使其生效。 此外,Xdebug还可以跟踪程序的运行,迅速找到程序运行的瓶颈所在PHP错误处理,从而提高程序开发效率。 小结:PHP从入门到精通—错误与异常处理—错误处理、异常处理、调试方法 介绍了错误处理、异常处理及调试方法。对于错误,大家需了解其类型与级别,并根据具体情况做不同的处理。对于异常,大家需掌握其处理方法,包括自定义异常、多个异常、重抛异常。 (编辑:天瑞地安资讯网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |