例外用于如果发生指定的错误改变脚本的正常流动。
什么是异常
随着PHP 5来处理错误的一个新的面向对象的方式。
异常处理用于如果指定的错误改变代码执行的正常流动(exceptional)条件发生。 这种情况被称为异常。
这是当异常被触发,通常会发生什么:
- 当前代码状态被保存
- 该代码执行将切换到预定义的(custom)异常处理函数
- 根据不同的情况,处理程序就可以恢复的代码保存状态下执行,中止执行脚本或从其他位置继续脚本代码
我们会表现出不同的错误处理方法:
- 基本使用的例外
- 创建自定义异常处理程序
- 多个异常
- 重新抛出异常
- 设置顶层异常处理程序
Note:例外只应该错误的条件下使用,而不应使用在指定点跳转到另一地点的代码。
例外的基本使用
当一个异常被抛出,下面的代码就不会被执行,而PHP将试图找到匹配的"catch"块。
如果一个异常没有被捕获,一个致命的错误将与发出"Uncaught Exception"消息。
让我们试着抛出一个异常,不会夹住它:
<?php
//create function with an exception
function checkNum($number) {
if($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception
checkNum(2);
?>
上面的代码会获得类似这样的错误:
Fatal error : Uncaught exception 'Exception'
with message 'Value must be 1 or below' in C:\webfolder\test.php:6
Stack trace: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6
尝试,抛出和捕获
为了避免从上面例子中的错误,我们需要创建适当的代码来处理异常。
适当的异常代码应包括:
- 使用异常应在一个功能-尝试"try"块。 如果异常不会触发,代码将继续正常。 但是,如果触发的例外,一个异常"thrown"
- 扔掉 - 这是你如何触发一个例外。 每一个"throw"必须至少有一个"catch"
- 捉-甲"catch"块检索一个例外,并创建包含异常信息的对象
让我们尝试触发有效代码的异常:
<?php
//create function with an exception
function checkNum($number) {
if($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception in a "try" block
try {
checkNum(2);
//If the exception is thrown, this text will not be shown
echo 'If you see this, the number is 1 or below';
}
//catch exception
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
?>
上面的代码会获得类似这样的错误:
Message: Value must be 1 or below
为例进行了说明:
上面的代码抛出异常和捕获它:
- 所述checkNum()创建功能。 它检查,如果数大于1,如果是,则抛出异常
- 该checkNum()函数被调用一个"try"块
- 该范围内的异常checkNum()函数抛出
- 的"catch"块检索异常,并创建一个对象($e)包含异常信息
- 从异常的错误消息是由呼叫呼应$e-> getMessage()从所述异常对象
然而,一个办法让周围的"every throw must have a catch"规则是设定一个最高水平异常处理程序来处理漏网之鱼错误。
创建一个自定义异常类
要创建您必须创建一个特殊类时异常在PHP时,可以调用函数的自定义异常处理程序。 类必须是异常类的扩展。
自定义异常类从PHP的异常类继承的属性,你可以添加自定义的功能吧。
让我们创建一个异常类:
<?php
class customException extends Exception {
public function errorMessage() {
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "[email protected]";
try {
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new customException($email);
}
}
catch (customException $e) {
//display custom message
echo $e->errorMessage();
}
?>
新的类是旧的例外类与另外的一个副本errorMessage()函数。 既然是老类的副本,并将其从旧的类继承的属性和方法,我们可以使用异常类的方法,如getLine()和getFile()和getMessage()
为例进行了说明:
上面的代码抛出异常,并用一个定制的异常类捕获它:
- 该customException()类为旧的例外类的扩展创建。 这样,它继承了旧的例外类的所有方法和属性
- 所述errorMessage()创建功能。 如果电子邮件地址无效,该函数返回一个错误信息
- 在$电子邮件变量设置为一个字符串,这不是一个有效的电子邮件地址
- 在"try"块被执行并抛出一个异常,因为电子邮件地址无效
- 的"catch"块捕捉异常并显示错误消息
多个异常
这是可能的脚本中使用多个异常检查多个条件。
有可能使用几种的if..else块,一个开关,或嵌套多个异常。 这些例外可以使用不同的异常类返回不同的错误信息:
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "[email protected]";
try {
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new customException($email);
}
//check for "example" in mail address
if(strpos($email, "example") !== FALSE) {
throw new Exception("$email is an example e-mail");
}
}
catch (customException $e) {
echo $e->errorMessage();
}
catch(Exception $e) {
echo $e->getMessage();
}
?>
为例进行了说明:
上面的代码测试两个条件,并且如果任一条件不满足抛出异常:
- 该customException()类为旧的例外类的扩展创建。 这样,它继承了旧的例外类的所有方法和属性
- 所述errorMessage()创建功能。 如果电子邮件地址无效,该函数返回一个错误信息
- 在$电子邮件变量设置为一个字符串,是一个有效的电子邮件地址,但包含字符串"example"
- 在"try"块被执行,一个异常没有抛出的第一个条件
- 由于电子邮件包含字符串的第二个条件触发的异常"example"
- 的"catch"块捕捉异常并显示正确的错误消息
如果抛出的异常是类customException并没有customException抓,只有基本异常捕获,异常将在那里处理。
重新抛出异常
有时,当抛出一个异常,你可能希望以不同的方式处理它比标准的方式。 它可以抛出一个异常内的第二次"catch"块。
脚本应该对用户隐藏系统错误。 系统错误可能是编码器很重要,但不感兴趣的用户。 为了让事情变得更容易为用户,您可以重新引发与用户友好的消息的异常:
<?php
class customException extends Exception {
public function errorMessage() {
//error message
$errorMsg = $this->getMessage().' is not a valid E-Mail address.';
return $errorMsg;
}
}
$email = "[email protected]";
try {
try {
//check for "example" in mail address
if(strpos($email, "example") !== FALSE) {
//throw exception if email is not valid
throw new Exception($email);
}
}
catch(Exception $e) {
//re-throw exception
throw new customException($email);
}
}
catch (customException $e) {
//display custom message
echo $e->errorMessage();
}
?>
为例进行了说明:
上述测试的代码,如果电子邮件地址包含字符串"example"在里面,如果这样做,异常被重新抛出:
- 该customException()类为旧的例外类的扩展创建。 这样,它继承了旧的例外类的所有方法和属性
- 所述errorMessage()创建功能。 如果电子邮件地址无效,该函数返回一个错误信息
- 在$电子邮件变量设置为一个字符串,是一个有效的电子邮件地址,但包含字符串"example"
- 在"try"块包含另一个"try"块,使之可能重新抛出异常
- 被触发的异常,因为电子邮件包含字符串"example"
- 在"catch"块捕获该异常,并重新抛出一个"customException"
- 所述"customException"被捕获并显示错误消息
如果该异常不能在其目前陷入"try"块,它将搜索在catch块"higher levels" 。
设置顶层异常处理
所述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
在上面的代码没有"catch"块。 取而代之的是,顶层异常处理触发。 此功能可用于捕捉未捕获的异常。
规则的例外
- 代码可以在try块包围,以帮助捕捉到潜在的异常
- 每个try块或"throw"必须至少有一个与之对应的catch
- 多个catch可以用来捕获不同的类的例外
- 异常可以被抛出(or re-thrown)在catch块try块内
一个简单的规则:如果你扔东西,你必须抓住它。