设为首页收藏本站language 语言切换
查看: 1645|回复: 0
收起左侧

PHP语言参考 - 异常处理

[复制链接]
发表于 2010-2-24 13:38:57 | 显示全部楼层 |阅读模式
<DIV class=chapter lang=zh-cn><DIV class=titlepage><DIV><DIV><H1><A name=language.exceptions></A>第 20 章 异常处理</H1></DIV></DIV></DIV><H2>目录</H2><DL><DT><U><FONT color=#800080>扩展 PHP 内置的异常处理类</FONT></U></DT></DL><>HP 5 添加了类似于其它语言的异常处理模块。在 PHP 代码中所产生的异常可被 <VAR>throw</VAR> 语句抛出并被 <VAR>catch</VAR> 语句捕获。需要进行异常处理的代码都必须放入 <VAR>try</VAR> 代码块内,以便捕获可能存在的异常。每一个 <VAR>try</VAR> 至少要有一个与之对应的 <VAR>catch</VAR>。使用多个 <VAR>catch</VAR> 可以捕获不同的类所产生的异常。当 <VAR>try</VAR> 代码块不再抛出异常或者找不到 <VAR>catch</VAR> 能匹配所抛出的异常时,PHP 代码就会在跳转到最后一个 catch 的后面继续执行。当然,PHP 允许在 <VAR>catch</VAR> 代码块内再次抛出(<VAR>throw</VAR>)异常。 </P><>当一个异常被抛出时,其后(译者注:指抛出异常时所在的代码块)的代码将不会继续执行,而 PHP 就会尝试查找第一个能与之匹配的 <VAR>catch</VAR>。如果一个异常没有被捕获,而且又没用使用 <A href="http://www.php.net/manual/zh/function.set-exception-handler.php"><U><FONT color=#0000ff>set_exception_handler()</FONT></U></A> 作相应的处理的话,那么 PHP 将会产生一个严重的错误,并且输出 <VAR>Uncaught Exception ...</VAR> (未捕获异常)的提示信息。 </P><DIV class=example><A name=id2695988></A><><B>例 20.1. 抛出一个异常</B></P><DIV class=example-contents><DIV class=phpcode><CODE><SPAN class=html><SPAN class=default>&lt;?php<BR></SPAN><SPAN class=keyword>try {<BR>    </SPAN><SPAN class=default>$error </SPAN><SPAN class=keyword>= </SPAN><SPAN class=string>'Always throw this error'</SPAN><SPAN class=keyword>;<BR>    throw new </SPAN><SPAN class=default>Exception</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$error</SPAN><SPAN class=keyword>);<BR><BR>    </SPAN><SPAN class=comment>// 从这里开始,tra 代码块内的代码将不会被执行<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>'Never executed'</SPAN><SPAN class=keyword>;<BR><BR>} catch (</SPAN><SPAN class=default>Exception $e</SPAN><SPAN class=keyword>) {<BR>    echo </SPAN><SPAN class=string>'Caught exception: '</SPAN><SPAN class=keyword>,  </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>-&gt;</SPAN><SPAN class=default>getMessage</SPAN><SPAN class=keyword>(), </SPAN><SPAN class=string>"\n"</SPAN><SPAN class=keyword>;<BR>}<BR><BR></SPAN><SPAN class=comment>// 继续执行<BR></SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>'Hello World'</SPAN><SPAN class=keyword>;<BR></SPAN><SPAN class=default>?&gt;</SPAN></SPAN></CODE></DIV></DIV></DIV><BR class=example-break><DIV class=sect1 lang=zh-cn><DIV class=titlepage><DIV><DIV><H1><A name=language.exceptions.extending></A>扩展 PHP 内置的异常处理类</H1></DIV></DIV></DIV><>用户可以用自定义的异常处理类来扩展 PHP 内置的异常处理类。以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的。译者注:以下这段代码只为说明内置异常处理类的结构,它并不是一段有实际意义的可用代码。 </P><DIV class=example><A name=id2696037></A><><B>例 20.2. 内置的异常处理类</B></P><DIV class=example-contents><DIV class=phpcode><CODE><SPAN class=html><SPAN class=default>&lt;?php<BR></SPAN><SPAN class=keyword>class </SPAN><SPAN class=default>Exception<BR></SPAN><SPAN class=keyword>{<BR>    protected </SPAN><SPAN class=default>$message </SPAN><SPAN class=keyword>= </SPAN><SPAN class=string>'Unknown exception'</SPAN><SPAN class=keyword>;   </SPAN><SPAN class=comment>// 异常信息<BR>    </SPAN><SPAN class=keyword>protected </SPAN><SPAN class=default>$code </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>0</SPAN><SPAN class=keyword>;                        </SPAN><SPAN class=comment>// 用户自定义异常代码<BR>    </SPAN><SPAN class=keyword>protected </SPAN><SPAN class=default>$file</SPAN><SPAN class=keyword>;                            </SPAN><SPAN class=comment>// 发生异常的文件名<BR>    </SPAN><SPAN class=keyword>protected </SPAN><SPAN class=default>$line</SPAN><SPAN class=keyword>;                            </SPAN><SPAN class=comment>// 发生异常的代码行号<BR><BR>    </SPAN><SPAN class=keyword>function </SPAN><SPAN class=default>__construct</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$message </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>null</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$code </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>0</SPAN><SPAN class=keyword>);<BR><BR>    final function </SPAN><SPAN class=default>getMessage</SPAN><SPAN class=keyword>();                </SPAN><SPAN class=comment>// 返回异常信息<BR>    </SPAN><SPAN class=keyword>final function </SPAN><SPAN class=default>getCode</SPAN><SPAN class=keyword>();                   </SPAN><SPAN class=comment>// 返回异常代码<BR>    </SPAN><SPAN class=keyword>final function </SPAN><SPAN class=default>getFile</SPAN><SPAN class=keyword>();                   </SPAN><SPAN class=comment>// 返回发生异常的文件名<BR>    </SPAN><SPAN class=keyword>final function </SPAN><SPAN class=default>getLine</SPAN><SPAN class=keyword>();                   </SPAN><SPAN class=comment>// 返回发生异常的代码行号<BR>    </SPAN><SPAN class=keyword>final function </SPAN><SPAN class=default>getTrace</SPAN><SPAN class=keyword>();                  </SPAN><SPAN class=comment>// backtrace() 数组<BR>    </SPAN><SPAN class=keyword>final function </SPAN><SPAN class=default>getTraceAsString</SPAN><SPAN class=keyword>();          </SPAN><SPAN class=comment>// 已格成化成字符串的 getTrace() 信息<BR><BR>    /* 可重载的方法 */<BR>    </SPAN><SPAN class=keyword>function </SPAN><SPAN class=default>__toString</SPAN><SPAN class=keyword>();                       </SPAN><SPAN class=comment>// 可输出的字符串<BR></SPAN><SPAN class=keyword>}<BR></SPAN><SPAN class=default>?&gt;</SPAN></SPAN></CODE></DIV></DIV></DIV><BR class=example-break><>如果使用自定义的类来扩展内置异常处理类,并且要重新定义<A title=构造函数和析构函数 href="http://www.php.net/manual/zh/language.oop5.decon.php"><U><FONT color=#0000ff>构造函数</FONT></U></A>的话,建议同时调用 <A title=范围解析操作符(::) href="http://www.php.net/manual/zh/language.oop5.paamayim-nekudotayim.php"><U><FONT color=#0000ff>parent::__construct()</FONT></U></A> 来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载 <A title="Magic Methods" href="http://www.php.net/manual/zh/language.oop5.magic.php"><U><FONT color=#0000ff>__toString()</FONT></U></A> 并自定义输出的样式。 </P><DIV class=example><A name=id2696118></A><><B>例 20.3. 扩展 PHP 内置的异常处理类</B></P><DIV class=example-contents><DIV class=phpcode><CODE><SPAN class=html><SPAN class=default>&lt;?php<BR></SPAN><SPAN class=comment>/**<BR> * 自定义一个异常处理类<BR> */<BR></SPAN><SPAN class=keyword>class </SPAN><SPAN class=default>MyException </SPAN><SPAN class=keyword>extends </SPAN><SPAN class=default>Exception<BR></SPAN><SPAN class=keyword>{<BR>    </SPAN><SPAN class=comment>// 重定义构造器使 message 变为必须被指定的属性<BR>    </SPAN><SPAN class=keyword>public function </SPAN><SPAN class=default>__construct</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$message</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$code </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>0</SPAN><SPAN class=keyword>) {<BR>        </SPAN><SPAN class=comment>// 自定义的代码<BR><BR>        // 确保所有变量都被正确赋值<BR>        </SPAN><SPAN class=default>parent</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>__construct</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$message</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$code</SPAN><SPAN class=keyword>);<BR>    }<BR><BR>    </SPAN><SPAN class=comment>// 自定义字符串输出的样式<BR>    </SPAN><SPAN class=keyword>public function </SPAN><SPAN class=default>__toString</SPAN><SPAN class=keyword>() {<BR>        return </SPAN><SPAN class=default>__CLASS__ </SPAN><SPAN class=keyword>. </SPAN><SPAN class=string>": [{$this-&gt;code}]: {$this-&gt;message}\n"</SPAN><SPAN class=keyword>;<BR>    }<BR><BR>    public function </SPAN><SPAN class=default>customFunction</SPAN><SPAN class=keyword>() {<BR>        echo </SPAN><SPAN class=string>"A Custom function for this type of exception\n"</SPAN><SPAN class=keyword>;<BR>    }<BR>}<BR><BR><BR></SPAN><SPAN class=comment>/**<BR> * 创建一个用于测试异常处理机制的类<BR> */<BR></SPAN><SPAN class=keyword>class </SPAN><SPAN class=default>TestException<BR></SPAN><SPAN class=keyword>{<BR>    public </SPAN><SPAN class=default>$var</SPAN><SPAN class=keyword>;<BR><BR>    const </SPAN><SPAN class=default>THROW_NONE    </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>0</SPAN><SPAN class=keyword>;<BR>    const </SPAN><SPAN class=default>THROW_CUSTOM  </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>1</SPAN><SPAN class=keyword>;<BR>    const </SPAN><SPAN class=default>THROW_DEFAULT </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>2</SPAN><SPAN class=keyword>;<BR><BR>    function </SPAN><SPAN class=default>__construct</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$avalue </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>self</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>THROW_NONE</SPAN><SPAN class=keyword>) {<BR><BR>        switch (</SPAN><SPAN class=default>$avalue</SPAN><SPAN class=keyword>) {<BR>            case </SPAN><SPAN class=default>self</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>THROW_CUSTOM</SPAN><SPAN class=keyword>:<BR>                </SPAN><SPAN class=comment>// 抛出自定义异常<BR>                </SPAN><SPAN class=keyword>throw new </SPAN><SPAN class=default>MyException</SPAN><SPAN class=keyword>(</SPAN><SPAN class=string>'1 is an invalid parameter'</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>5</SPAN><SPAN class=keyword>);<BR>                break;<BR><BR>            case </SPAN><SPAN class=default>self</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>THROW_DEFAULT</SPAN><SPAN class=keyword>:<BR>                </SPAN><SPAN class=comment>// 抛出默认的异常<BR>                </SPAN><SPAN class=keyword>throw new </SPAN><SPAN class=default>Exception</SPAN><SPAN class=keyword>(</SPAN><SPAN class=string>'2 isnt allowed as a parameter'</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>6</SPAN><SPAN class=keyword>);<BR>                break;<BR><BR>            default:<BR>                </SPAN><SPAN class=comment>// 没有异常的情况下,创建一个对象<BR>                </SPAN><SPAN class=default>$this</SPAN><SPAN class=keyword>-&gt;</SPAN><SPAN class=default>var </SPAN><SPAN class=keyword>= </SPAN><SPAN class=default>$avalue</SPAN><SPAN class=keyword>;<BR>                break;<BR>        }<BR>    }<BR>}<BR><BR><BR></SPAN><SPAN class=comment>// 例子 1<BR></SPAN><SPAN class=keyword>try {<BR>    </SPAN><SPAN class=default>$o </SPAN><SPAN class=keyword>= new </SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>THROW_CUSTOM</SPAN><SPAN class=keyword>);<BR>} catch (</SPAN><SPAN class=default>MyException $e</SPAN><SPAN class=keyword>) {      </SPAN><SPAN class=comment>// 捕获异常<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>"Caught my exception\n"</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>;<BR>    </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>-&gt;</SPAN><SPAN class=default>customFunction</SPAN><SPAN class=keyword>();<BR>} catch (</SPAN><SPAN class=default>Exception $e</SPAN><SPAN class=keyword>) {        </SPAN><SPAN class=comment>// 被忽略<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>"Caught Default Exception\n"</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>;<BR>}<BR><BR></SPAN><SPAN class=comment>// 执行后续代码<BR></SPAN><SPAN class=default>var_dump</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$o</SPAN><SPAN class=keyword>);<BR>echo </SPAN><SPAN class=string>"\n\n"</SPAN><SPAN class=keyword>;<BR><BR><BR></SPAN><SPAN class=comment>// 例子 2<BR></SPAN><SPAN class=keyword>try {<BR>    </SPAN><SPAN class=default>$o </SPAN><SPAN class=keyword>= new </SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>THROW_DEFAULT</SPAN><SPAN class=keyword>);<BR>} catch (</SPAN><SPAN class=default>MyException $e</SPAN><SPAN class=keyword>) {      </SPAN><SPAN class=comment>// 不能匹配异常的种类,被忽略<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>"Caught my exception\n"</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>;<BR>    </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>-&gt;</SPAN><SPAN class=default>customFunction</SPAN><SPAN class=keyword>();<BR>} catch (</SPAN><SPAN class=default>Exception $e</SPAN><SPAN class=keyword>) {        </SPAN><SPAN class=comment>// 捕获异常<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>"Caught Default Exception\n"</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>;<BR>}<BR><BR></SPAN><SPAN class=comment>// 执行后续代码<BR></SPAN><SPAN class=default>var_dump</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$o</SPAN><SPAN class=keyword>);<BR>echo </SPAN><SPAN class=string>"\n\n"</SPAN><SPAN class=keyword>;<BR><BR><BR></SPAN><SPAN class=comment>// 例子 3<BR></SPAN><SPAN class=keyword>try {<BR>    </SPAN><SPAN class=default>$o </SPAN><SPAN class=keyword>= new </SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>::</SPAN><SPAN class=default>THROW_CUSTOM</SPAN><SPAN class=keyword>);<BR>} catch (</SPAN><SPAN class=default>Exception $e</SPAN><SPAN class=keyword>) {        </SPAN><SPAN class=comment>// 捕获异常<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>"Default Exception caught\n"</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>;<BR>}<BR><BR></SPAN><SPAN class=comment>// 执行后续代码<BR></SPAN><SPAN class=default>var_dump</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$o</SPAN><SPAN class=keyword>);<BR>echo </SPAN><SPAN class=string>"\n\n"</SPAN><SPAN class=keyword>;<BR><BR><BR></SPAN><SPAN class=comment>// 例子 4<BR></SPAN><SPAN class=keyword>try {<BR>    </SPAN><SPAN class=default>$o </SPAN><SPAN class=keyword>= new </SPAN><SPAN class=default>TestException</SPAN><SPAN class=keyword>();<BR>} catch (</SPAN><SPAN class=default>Exception $e</SPAN><SPAN class=keyword>) {        </SPAN><SPAN class=comment>// 没有异常,被忽略<BR>    </SPAN><SPAN class=keyword>echo </SPAN><SPAN class=string>"Default Exception caught\n"</SPAN><SPAN class=keyword>, </SPAN><SPAN class=default>$e</SPAN><SPAN class=keyword>;<BR>}<BR><BR></SPAN><SPAN class=comment>// 执行后续代码<BR></SPAN><SPAN class=default>var_dump</SPAN><SPAN class=keyword>(</SPAN><SPAN class=default>$o</SPAN><SPAN class=keyword>);<BR>echo </SPAN><SPAN class=string>"\n\n"</SPAN><SPAN class=keyword>;<BR></SPAN><SPAN class=default>?&gt;</SPAN></SPAN></CODE></DIV></DIV></DIV></DIV></DIV>
您需要登录后才可以回帖 登录 | 论坛注册

本版积分规则

QQ|Archiver|手机版|小黑屋|sitemap|鸿鹄论坛 ( 京ICP备14027439号 )  

GMT+8, 2025-4-5 19:59 , Processed in 0.087158 second(s), 22 queries , Redis On.  

  Powered by Discuz!

  © 2001-2025 HH010.COM

快速回复 返回顶部 返回列表