您的位置:首页 > 编程语言 > PHP开发

php异常详解

2012-07-16 11:43 621 查看
php处理异常大概借鉴了Java的异常处理机制。

所以在PHP中异常处理是用try,catch和throw。

在PHP中,检测异常的是try,捕获异常的是catch,所以抛出异常的是throw。

php异常处理的原理是什么呢?

在PHP程序中,程序开始执行,然后运行到try,检测是否有异常,如果有异常,并且抛出了异常(throw),则php程序通过catch捕获异常,对异常进行处理。

如果没有异常,或者没有抛出异常,则继续执行其余的程序,直至程序执行完毕。

-----------------------------------------------------------------------------------

PHP如何处理exception的呢?

在PHP中建立好exception对象之后,就需要使用throw抛出异常。

使用PHP关键词抛出异常,语法如下:

throw $e;

$e是使用exception建立的异常对象。

在使用PHP中,为了优化代码,往往在抛出异常时建立异常对象,例如:

throw new exception([string $errmsg])

例如:

<?php
$path = "D:\\www.phpdo.net";
file_open($path);
function file_open($path)
{
if($path)
{
echo "文件存在";
}
else if(!file_extst($path))
{
throw new exception("文件不存在",1);
}
else if(!fopen($path,"r"))
{
throw new exception("文件无法打开",2);
}
}
?>

因为在这个PHP程序中,我没有捕获异常,所以,结果为:

Fatal error: Uncaught exception ‘Exception’ with message ‘www.phpdo.net这个文件不存在’ in E:\xampp\htdocs\php\Test\10.2.3.php:9 Stack trace: #0 E:\xampp\htdocs\php\Test\10.2.3.php(3): file_open(‘E:\www.phpdo.ne…’) #1 {main} thrown in E:\xampp\htdocs\php\Test\10.2.3.php on line 9

--------------------------------------------------------------------------------
php的异常类exception
发表于540 天前 ⁄ php-基础语法 ⁄ 评论数 2

在PHP中的异常处理程序中,一个try必须与一个或多个throw相对应,在throw中定义的顺序就是异常的检测顺序。

使用throw抛出异常,必须要使用PHP的异常类exception。

Exception类的定义是怎样的呢?

代码如下:

<?php
class exception
{
protected $message = 'Unknow exception'; //自定义的异常信息
protected $code = 0; //定义的异常代码
protected $file; //发生异常的PHP程序名
protected $line; //发生异常的PHP行号
//用于传递用户自定义异常信息和用户自定义异常代码的构造函数
function __construct($message=null,$code=0);
final function getMessage();
final function getCode();
final function getFile();
final function getLine();
final function getTrace(); //以数组形式返回异常传递的路线
final function getTraceAsString(); //返回格式化成字符串的getTrace函数信息
function __toString(); //可重载,用于返回可输出的字符串
}
?>

exception建立的异常对象用于存储异常信息并用于抛出和捕获异常。

建立异常对象的语法格式如下:

$e = new Exception([string $errmsg[,int $errcode]]);

$errmsg是用户自定义的异常信息,$errcode为用户自定义的代码。

例如:

<?php
$e = new Exception("www.phpdo.net发生错误",23);
echo $e->getMessage();
echo $e->getCode();
echo $e->getFile();
echo $e->getLine();
?>

结果:

www.phpdo.net 发生错误

23

E:\xampp\htdocs\php\Test\10.2.2.php

2

-------------------------------------------------------------------------------

php如何捕获异常
发表于535 天前 ⁄ php-基础语法 ⁄ 暂无评论

用PHP的关键词throw抛出异常之后,需要使用catch捕获异常。

在PHP中使用catch需要与try配套使用,语法如下:

try{

//可能会产生异常的语句

}

catch(Exception $e){

捕获异常后的操作

}

对上文phpdo的例子,补充如下:

<?php
$path = "E:\\www.phpdo.net";
try
{
file_open($path);
}
catch(Exception $e)
{
echo $e->getMessage();
}
function file_open($path)
{
if(!file_exists($path))
{
throw new exception("www.phpdo.net这个文件不存在",1);
}
if(!fopen($path,"r"))
{
throw new exception("www.phpdo.net这个文件无法打开",2);
}
}
?>

结果:

www.phpdo.net 这个文件不存在

--------------------------------------------------------------------------
PHP处理异常的函数
发表于534 天前 ⁄ php-基础语法 ⁄ 暂无评论

使用PHP时不可能将所有的异常都使用检测函数try,所以在实际应用中就有PHP处理异常的函数,用这个专门的函数对异常进行处理。当有异常抛出,而没有捕获(一般意味着没有使用 try catch,直接使用throw抛出了异常,这样子的话。这个异常没有被捕获到),时会自动调用这个自宝义的函数

在PHP中使用set_exception_handler函数设置这个异常函数,语法如下:

set_exception_handler(exception_handler)

exception_handler为用于处理未捕获异常的函数名称。

这个异常处理函数语法如下:

function exception_handler($e){}

$e是异常对象。

有一点值得注意:这个函数的定义须在set_exception_handler函数之前。

例如:

<?php
function exception_handler($e)
{//用于处理异常的函数
echo "未捕获的异常:".$e->getMessage();
}
set_exception_handler("exception_handler");
try
{
$path = "www.phpdo.net";
}
catch(Exception $e)
{
echo $e->getMessage();
}
file_open($path);//没有检测这个函数
function file_open($path)
{
if(!file_exists($path))
{
throw new exception("www.phpdo.net这个文件不存在",1);
}
if(!fopen($path,"r"))
{
throw new exception("www.phpdo.net这个文件无法打开",2);
}
}
?>

结果:

未捕获的异常:www.phpdo.net 这个文件不存在

-------------------------------------------------

PHP的getTrace
发表于533 天前 ⁄ php-基础语法 ⁄ 暂无评论

每个PHP程序员都会想要跟踪异常的传递路线,PHP的getTrace函数以数组的形式实现了这个功能。
PHP的getTrace函数,主要包括一些键值:

fiel:发生异常的PHP程序文件名称;
line:发生异常的代码所在的行号;
function:发生异常的函数或方法;
class:发生异常的函数或方法所在的类;
type:调用发生异常的函数或方法的类型(“::”调用静态类成员,“->”调用实例化对象);
args:发生异常的函数或方法所接受的参数。

例如:

<?php
$path = "www.phpdo.net";
try
{
file_open($path);
}
catch(Exception $e)
{
echo "异常信息".$e->getMessage()."\n";
echo "异常代码".$e->getCode()."\n";
echo "异常文件".$e->getFile()."\n";
echo "异常代码所在行".$e->getLine()."\n";
echo "传递路线:";
print_r($e->getTrace()); //以数组的形式返回跟踪异常的每一部的传递路线
echo $e->getTraceAsString();//返回格式化成字符串的getTrace函数信息
}

function file_open($path)
{
if(!file_exists($path))
{
throw new exception("www.phpdo.net这个文件不存在",1);
}
if(!fopen($path,"r"))
{
throw new exception("www.phpdo.net这个文件无法打开",2);
}
}
?>

结果:

异常信息www.phpdo.net 这个文件不存在 异常代码1 异常文件E:\xampp\htdocs\php\Test\10.2.6.php 异常代码所在行22

传递路线:

Array ( [0] => Array ( [file] => E:\xampp\htdocs\php\Test\10.2.6.php [line] => 5 [function] => file_open [args] => Array ( [0] => www.phpdo.net ) ) )

#0 E:\xampp\htdocs\php\Test\10.2.6.php(5): file_open(‘www.phpdo.net’) #1 {main}

--------------------------------------------------------

php扩展异常处理类
发表于531 天前 ⁄ php-基础语法 ⁄ 暂无评论

使用PHP编程时,虽然可以跟踪异常的路线,但是在实际应用中需要使用不同的异常处理类处理不同的异常。

所以,PHP扩展异常处理类就产生了。

例如:

<?php
class FileExists extends Exception
{
//文件不存在异常
}
class FileOpen extends Exception
{
//文件不能打开异常
}
$path = "E://www.phpdo.net";
try
{
open_file($path);
}
catch(FileExists $e)
{
echo "程序运行异常: ".$e->getMessage()."\n";
}
catch(FileOpen $e)
{
echo "程序运行异常,".$e->getMessage()."\n";
}
catch(Exception $e)
{
echo "不可预知的异常";
echo "异常信息:".$e->getMessage()."\n";
echo "异常代码:".$e->getCode()."\n";
echo "文件名:".$e->getFile()."\n";
echo "异常代码所在的行".$e->getLine()."\n";
echo "异常信息传递路线:";
print_r($e->getTrace()); //返回数组形式的传递路线
echo $e->getTraceAsString(); //返回字符串形式的传递路线
}

function open_file($path)
{
if(!file_exists($path))
{
//抛出FileExists异常
throw new FileExists("www.phpdo.net不存在",1);
}
if(!fopen("$path",r))
{
//抛出FileOpen异常
throw new FileOpen("www.phpdo.net无法打开",2);
}
}
?>

结果:

程序运行异常: http://www.phpdo.net/不存在
php扩展异常处理类时需要注意的是:

捕获特定异常时,还需要捕获Exception类,用于处理未捕获的异常;
捕获异常时,需要按照顺序从上向下捕获(如果先捕获Exception类,则会导致异常不能被正确的代码处理,例如将“catch(Exception $e)“语句放到“catch(FileExists $e)”之前,会发生什么?)所以在设定时,需要将特定异常的catch语句写在前面,将一般的Exception语句写在最后。

根据这个例子,看出使用php扩展异常处理类的优点是什么呢?

提高代码的可读性,使得不同的异常容易被区分;

可自定义扩展类;
根据不同的异常做出不同的反应。
异常可以一级级向上传递,直到被捕获,不用担心在某个函数内部抛出的异常,在外层如何接收值

-----------------------------------------------------

php如何处理异常的传递与重置
发表于530 天前 ⁄ php-基础语法 ⁄ 暂无评论

有时在PHP的实际应用中,我们希望保留这个异常,将异常传递给上一层代码之后,在适当的时机进行处理。

php如何处理异常的传递与重置呢?

在PHP中通过调用catch语句再次抛出异常(将抛出的异常对象的处理方法交回调用当前方法),使异常向上传递。

例如:

<?php
class FileExists extends Exception
{
//文件不存在异常
}
class FileOpen extends Exception
{
//文件不能打开异常
}
$path = "E://www.phpdo.net";
try
{
open_file($path);
}
catch(FileExists $e)
{
echo "程序运行异常: ".$e->getMessage()."\n";
}
catch(FileOpen $e)
{
echo "程序运行异常,".$e->getMessage()."\n";
}
catch(Exception $e)
{
echo "不可预知的异常";
echo "异常信息:".$e->getMessage()."\n";
echo "异常代码:".$e->getCode()."\n";
echo "文件名:".$e->getFile()."\n";
echo "异常代码所在的行".$e->getLine()."\n";
echo "异常信息传递路线:";
print_r($e->getTrace()); //返回数组形式的传递路线
echo $e->getTraceAsString(); //返回字符串形式的传递路线
}

function open_file($path)
{
try
{
if(!file_exists($path))
{
//抛出FileExists异常
throw new FileExists("www.phpdo.net不存在",1);
}
if(!fopen($path,r))
{
//抛出FileOpen异常
throw new FileOpen("www.phpdo.net无法打开",2);
}
}
catch(Exception $e)
{
echo "open_file出现了异常";
throw $e; //抛出异常对象,方便catch(FileExists $e),catch(FileOpen $e),catch(Exception $e)调用
}
}
?>

结果:

open_file出现了异常

程序运行异常: www.phpdo.net不存在

----------------------------------------------------------------------------------
Exception类
Exception类是所有异常的根类,我们可以继承 它来构建自己的异常类。异常类的构造函数可有两个可选的参数,一个 error message 用来措述异常类,和一个 error code。
异常类有一些有用的方法我们可以使用:
getMessage();
getCode();
getFile(); 哪个文件发生错误
getLine(); 错误在哪一行
getTrace(); 栈轨迹
getTraceAsString();
__toString();

来源:http://hwp2011.blog.51cto.com/3874564/710372
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: