Heim >Backend-Entwicklung >PHP-Tutorial >PHP 面向对象编程和设计模式 (4)_PHP教程
PHP高级程序设计 学习笔记 2014.06.12
异常经常被用来处理一些在程序正常执行中遇到的各种类型的错误。比如做数据库链接时,你就要处理数据库连接失败的情况。使用异常可以提高我们程序的容错特性,从而使我们的应用程序更加的稳定和健壮。
使用异常
PHP5 增加了类似其他语言的异常处理模块。在PHP代码中所产生的异常可被 throw 语句抛出并被 catch 语句捕获。需要进行异常处理的代码都必须放入到 try 代码块内,以便捕获可能存在的异常。每个try至少对应一个 catch 块。使用多个 catch 可以捕获不同的类所产生的异常。当 try 代码块不再抛出异常或者找不到 catch 能匹配所抛出的异常时,PHP 代码就会在跳转到最后一个 catch 的后面继续执行。当然,PHP 允许在 catch 代码块内再次抛出(throw)异常。
预定义异常 Exception
Exception 类是所有异常的基类,我们可以通过派生 Exception 类来达到自定义异常的目的。下面的清单列出了 Exception 的基本信息。
<span>Exception</span><span> { </span><span>/*</span><span> 属性 </span><span>*/</span> <span>protected</span> <span>string</span> <span>$message</span> ; <span>//</span><span>异常消息内容</span> <span>protected</span> int <span>$code</span> ; <span>//</span><span>异常代码</span> <span>protected</span> <span>string</span> <span>$file</span> ; <span>//</span><span>抛出异常的文件名</span> <span>protected</span> int <span>$line</span> ; <span>//</span><span>抛出异常在该文件中的行号</span> <span>/*</span><span> 方法 </span><span>*/</span> <span>public</span> __construct ([ <span>string</span> <span>$message</span> = "" [, int <span>$code</span> = 0 [, <span>Exception</span> <span>$previous</span> = <span>NULL</span> ]]] ) <span>//</span><span>异常构造函数</span> <span>final</span> <span>public</span> <span>string</span> getMessage ( void ) <span>//</span><span>获取异常消息内容</span> <span>final</span> <span>public</span> <span>Exception</span> getPrevious ( void ) <span>//</span><span>返回异常链中的前一个异常</span> <span>final</span> <span>public</span> int getCode ( void ) <span>//</span><span>获取异常代码</span> <span>final</span> <span>public</span> <span>string</span> getFile ( void ) <span>//</span><span>获取发生异常的程序文件名称</span> <span>final</span> <span>public</span> int getLine ( void ) <span>//</span><span>获取发生异常的代码在文件中的行号</span> <span>final</span> <span>public</span> <span>array</span> getTrace ( void ) <span>//</span><span>获取异常追踪信息</span> <span>final</span> <span>public</span> <span>string</span> getTraceAsString ( void ) <span>//</span><span>获取字符串类型的异常追踪信息</span> <span>public</span> <span>string</span> __toString ( void ) <span>//</span><span>将异常对象转换为字符串</span> <span>final</span> <span>private</span> void __clone ( void ) <span>//</span><span>异常克隆</span> }
了解完 Exception 后,我们来尝试扩展 exception 类来实现一个自定义异常。
<span>function</span><span> connectToDatabase() { </span><span>if</span>(!<span>$link</span> = <span>mysql_connect</span>("myhost","myuser","mypassw","mybd"<span>)) { </span><span>throw</span> <span>new</span> <span>Exception</span>("could not connect to the database."<span>); } } </span><span>try</span><span> { connectToDatabase(); } </span><span>catch</span>(<span>Exception</span> <span>$e</span><span>) {</span><span>echo</span> <span>$e</span>-><span>getMessage(); }</span>
这里我们抛出类一个 Exception 类型的异常,并在catch里捕获了这个异常,最终打印出了“could not connect to the database.”。或许你想还想显示数据库连接失败的原因信息。下面及通过扩展exception类来实现我们的自定义信息。
<span>class</span> MyException <span>extends</span> <span>Exception</span><span> { </span><span>protected</span> <span>$ErrorInfo</span><span>; </span><span>//</span><span>构造函里处理一些逻辑,然后将一些信息传递给基类</span> <span>public</span> <span>function</span> __construct(<span>$message</span>=<span>null</span>,<span>$code</span>=0<span>) { </span><span>$this</span>->ErrorInfo = '自定义错误类的错误信息'<span>; parent</span>::__construct(<span>$message</span>,<span>$code</span><span>); } </span><span>//</span><span>提供获取自定义类信息的方法</span> <span>public</span> <span>function</span><span> GetErrorInfo() { </span><span>return</span> <span>$this</span>-><span>ErrorInfo; } </span><span>/*</span><span>* * *这里还可以添加异常日志,只需在上面的构造函数里调用就可以了 * </span><span>*/</span> <span>public</span> <span>function</span> <span>log</span>(<span>$file</span><span>) { </span><span>file_put_contents</span>(<span>$fiel</span>,<span>$this</span>->__toString(),<span>FILE_APPEND); } } </span><span>function</span><span> connectToDatabase() { </span><span>throw</span> <span>new</span> MyException("ErrorMessage"<span>); } </span><span>try</span><span> { connectToDatabase(); } </span><span>catch</span>(MyException <span>$e</span><span>) { </span><span>echo</span> <span>$e</span>->getMessage() . "\n"<span>; </span><span>echo</span> <span>$e</span>-><span>GetErrorInfo(); }</span>
set_exception_handler 设置一个用户定义的异常处理函数
当一个未捕获的异常发生时所调用的函数名称作为set_exception_handler的参数。该函数必须在调用set_exception_handler()之前被定义。该函数接受一个参数,该参数是一个抛出的异常对象。这可以用来改进上边提到的异常记录日志处理。
<span>function</span> ExceptionLogger(<span>$exception</span><span>) { </span><span>$file</span>='ExceptionLog.log'<span>; </span><span>file_put_contents</span>(<span>$fiel</span>,<span>$exception</span>->__toString(),<span>FILE_APPEND); } </span><span>set_exception_handler</span>(ExceptionLogger);
1.3、PHP 允许在 catch 代码块内再次抛出(throw)异常。
<span>try</span><span> { </span><span>#</span><span>code...</span> <span>} </span><span>catch</span>(<span>Exception</span> <span>$e</span><span>) { </span><span>if</span>(<span>$e</span>->getCode() == 999<span>) { </span><span>#</span><span>进行一些操作</span> <span> } </span><span>else</span><span> { </span><span>throw</span> <span>$e</span><span>; } }</span>
总结
异常的功能非常强大,但是不以为着我们可以在项目中肆意的滥用异常机制,特别是大量使用异常日志的机制,这回大大增加系统系统开销降低应用程序的性能。利用错误代码我们可以方便的对错误信息进行管理,当一个错误信息被多次平抛出时,使用错误代码是科学的选择。我们甚至可以通过错误代码来让错误消息也支持多语言显示。