2014-09-05
异常处理(又称为错误处理)功能提供了处理程序运行时出现的错误或异常情况的方法。
异常处理通常是防止未知错误产生所采取的处理措施。异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。当异常被触发时,通常会发生:
当前代码状态被保存
代码执行被切换到预定义的异常处理器函数
根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本
PHP 5 提供了一种新的面向对象的错误处理方法。可以使用检测(try)、抛出(throw)和捕获(catch)异常。即使用try检测有没有抛出(throw)异常,若有异常抛出(throw),使用catch捕获异常。
一个 try 至少要有一个与之对应的 catch。定义多个 catch 可以捕获不同的对象。PHP 会按这些 catch 被定义的顺序执行,直到完成最后一个为止。而在这些 catch 内,又可以抛出新的异常。
1. 异常的使用
当一个异常被抛出时,其后的代码将不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。如果一个异常没有被捕获,而且又没用使用set_exception_handler() 作相应的处理的话,那么 PHP 将会产生一个严重的错误,并且输出未能捕获异常(Uncaught Exception ... )的提示信息。
抛出异常,但不去捕获它:
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL & ~ E_WARNING);
$error = 'Always throw this error';
throw new Exception($error);
// 继续执行
echo 'Hello World';
?>
上面的代码会获得类似这样的一个致命错误:
Fatal error: Uncaught exception 'Exception' with message 'Always throw this error' in E:/sngrep/index.php on line 5
Exception: Always throw this error in E:/sngrep/index.php on line 5
Call Stack:
0.0005 330680 1. {main}() E:/sngrep/index.php:0
2. Try, throw 和 catch
要避免上面这个致命错误,可以使用try catch捕获掉。
处理处理程序应当包括:
Try - 使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"
Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象
抛出异常并捕获掉,可以继续执行后面的代码:
<?php
try {
$error = 'Always throw this error';
throw new Exception($error);
// 从这里开始,tra 代码块内的代码将不会被执行
echo 'Never executed';
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(),'<br>';
}
// 继续执行
echo 'Hello World';
?>
在 "try" 代码块检测有有没有抛出“throw”异常,这里抛出了异常。
"catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。
通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息
为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。
3. 扩展 PHP 内置的异常处理类
用户可以用自定义的异常处理类来扩展 PHP 内置的异常处理类。以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的。(注:以下这段代码只为说明内置异常处理类的结构,它并不是一段有实际意义的可用代码。)
<?php
class Exception
{
protected $message = 'Unknown exception'; // 异常信息
protected $code = 0; // 用户自定义异常代码
protected $file; // 发生异常的文件名
protected $line; // 发生异常的代码行号
function __construct($message = null, $code = 0);
final function getMessage(); // 返回异常信息
final function getCode(); // 返回异常代码
final function getFile(); // 返回发生异常的文件名
final function getLine(); // 返回发生异常的代码行号
final function getTrace(); // backtrace() 数组 www.zhishiwu.com
final function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息
/* 可重载的方法 */
function __toString(); // 可输出的字符串
}
如果使用自定义的类来扩展内置异常处理类,并且要重新定义构造函数的话,建议同时调用 parent::__construct() 来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString() 并自定义输出的样式。
构建自定义异常处理类:
<?php
/**
*
* 自定义一个异常处理类
*/
class MyException extends Exception
{
// 重定义构造器使 message 变为必须被指定的属性
public function __construct($message, $code = 0) {
// 自定义的代码
// 确保所有变量都被正确赋值
parent::__construct($message, $code);
}
// 自定义字符串输出的样式 */
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}/n";
}
public function customFunction() {
echo "A Custom function for this type of exception/n";
}
}
// 例子 1:抛出自定义异常,但没有默认的异常
echo ' 例子 1', '<br>';
try {
// 抛出自定义异常
throw new MyException('1 is an invalid parameter', 5);
} catch (MyException $e) { // 捕获异常
echo "Caught my exception/n", $e;
$e->customFunction();
} catch (Exception $e) { // 被忽略
echo "Caught Default Exception/n", $e;
}
// 执行后续代码
// 例子 2: 抛出默认的异常 但没有自定义异常
echo '<br>', ' 例子 2:', '<br>';
try {
// 抛出默认的异常
throw new Exception('2 isnt allowed as a parameter', 6);
} catch (MyException $e) { // 不能匹配异常的种类,被忽略
echo "Caught my exception/n", $e;
$e->customFunction();
} catch (Exception $e) {// 捕获异常
echo "Caught Default Exception/n", $e;
}
// 执行后续代码
// 例子 3: 抛出自定义异常 ,使用默认异常类对象来捕获
echo '<br>', ' 例子 3:', '<br>';
try {
// 抛出自定义异常
throw new MyException('3 isnt allowed as a parameter', 6);
} catch (Exception $e) { // 捕获异常
echo "Default Exception caught/n", $e;
}
// 执行后续代码
// 例子 4
echo '<br>', ' 例子 4:', '<br>';
try {
echo 'No Exception ';
} catch (Exception $e) { // 没有异常,被忽略
echo "Default Exception caught/n", $e;
}
// 执行后续代码
MyException 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法,我们可以使用 exception 类的方法,比如 getLine() 、 getFile() 以及 getMessage()。
4. 嵌套异常处理
如果在内层 "try" 代码块中异常没有被捕获,则它将在外层级上查找 catch 代码块去捕获。
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
/* 重新抛出 rethrow it */
$e->customFunction();
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
5. 设置顶层异常处理器 (Top Level Exception Handler)
set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
输出结果:
Exception: Uncaught Exception occurred
6. 异常的规则
需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。
使用多个 catch 代码块可以捕获不同种类的异常。
可以在 try 代码块内的 catch 代码块中再次抛出(re-thrown)异常。
简而言之:如果抛出了异常,就必须捕获它,否则程序终止执行。
摘自 程序人生,guisu专栏
1
CI框架连接数据库配置操作以及多数据库操作
09-05
2
asp 简单读取数据表并列出来 ASP如何快速从数据库读取大量数据
05-17
3
C语言关键字及其解释介绍 C语言32个关键字详解
04-05
4
C语言中sizeof是什么意思 c语言里sizeof怎样用法详解
04-26
5
最简单的asp登陆界面代码 asp登陆界面源代码详细介绍
04-12
6
PHP中的魔术方法 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep,
09-05
7
PHP中的(++i)前缀自增 和 (i++)后缀自增
09-05
8
PHP中include和require区别之我见
09-05
常用dos命令及语法
2014-09-27
将视频设置为Android手机开机动画的教程
2014-12-11
php递归返回值的问题
2014-09-05
如何安装PHPstorm并配置方法教程 phpstorm安装后要进行哪些配置
2017-05-03
java中的info是什么意思
2022-03-24
PHP 教程之如何使用BLOB存取图片信息实例
2014-09-05
IcePHP框架中的快速后台中的通用CRUD功能框架
2014-09-05
单片机编程好学吗?单片机初学者怎样看懂代码
2022-03-21
PHP数组函数array
2014-09-05
学ug编程如何快速入门?
2022-03-17
英雄联盟云顶之弈手机版本下载v14.8.5768838 安卓最新版本
策略塔防 78.2M
下载苍蓝前线手游下载v1.1.0 安卓版
策略塔防 464.3M
下载崩坏学园2手游下载v12.2.8 安卓最新版本
角色扮演 323.3M
下载彩虹联萌手游下载v7.3.23015 安卓官方版
卡牌对战 804.7M
下载花花填色苹果版下载v2.2.5 iPhone版
其它手游 174M
下载奥特曼超时空英雄官方正版下载v1.0.2 安卓版
动作闯关 1.63G
下载全民奇迹2ios版下载v15.0.0 iphone版
其它手游 3G
下载罗布乐思roblox国际服最新版官方正版下载v2.682.538 安卓版
动作闯关 131.0M
下载com.roblox.client国际服下载v2.682.538 安卓版
下载
绝地鸭卫游戏下载v0.2.3 安卓版
下载
梦幻模拟战官服下载v6.13.2110 安卓最新版
下载
天龙八部手游8868版下载v1.133.2.2 安卓版
下载
天龙八部游戏下载v1.133.2.2 安卓手机版
下载
天龙八部手游果盘端下载v1.133.2.2 安卓版
下载
海贼王燃烧意志官方版下载v3.3.0.492700 安卓正版
下载
宝宝巴士安慰小宝宝下载v9.87.00.01 安卓版
下载