首頁 php教程 php手册 PHP异常处理详解

PHP异常处理详解

Jun 13, 2016 am 10:48 AM
php 出現 功能 處理 例外 情況 提供 方法 程式 詳解 運行時 錯誤

异常处理(又称为错误处理)功能提供了处理程序运行时出现的错误或异常情况的方法。

  异常处理通常是防止未知错误产生所采取的处理措施。异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。当异常被触发时,通常会发生:
          当前代码状态被保存
         代码执行被切换到预定义的异常处理器函数
          根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本

          PHP 5 提供了一种新的面向对象的错误处理方法。可以使用检测(try)、抛出(throw)和捕获(catch)异常。即使用try检测有没有抛出(throw)异常,若有异常抛出(throw),使用catch捕获异常。

         一个 try 至少要有一个与之对应的 catch。定义多个 catch 可以捕获不同的对象。PHP 会按这些 catch 被定义的顺序执行,直到完成最后一个为止。而在这些 catch 内,又可以抛出新的异常。

1. 异常的使用
        当一个异常被抛出时,其后的代码将不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。如果一个异常没有被捕获,而且又没用使用set_exception_handler() 作相应的处理的话,那么 PHP 将会产生一个严重的错误,并且输出未能捕获异常(Uncaught Exception ... )的提示信息。

     抛出异常,但不去捕获它:


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" 代码块会捕获异常,并创建一个包含异常信息的对象
       抛出异常并捕获掉,可以继续执行后面的代码:

try { 
    $error = 'Always throw this error'; 
    throw new Exception($error); 
 
    // 从这里开始,tra 代码块内的代码将不会被执行 
    echo 'Never executed'; 
 
} catch (Exception $e) { 
    echo 'Caught exception: ',  $e->getMessage(),'
'; 

 
// 继续执行 
echo 'Hello World'; 
?>  

    在 "try" 代码块检测有有没有抛出“throw”异常,这里抛出了异常。
    "catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。
    通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息
    为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。


3. 扩展 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.2cto.com  
    final function getTraceAsString();          // 已格成化成字符串的 getTrace() 信息 
 
    /* 可重载的方法 */ 
    function __toString();                       // 可输出的字符串 

       如果使用自定义的类来扩展内置异常处理类,并且要重新定义构造函数的话,建议同时调用 parent::__construct() 来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString() 并自定义输出的样式。

     构建自定义异常处理类:

 
/**
 * 
 * 自定义一个异常处理类
 */ 
 
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', '
'; 
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 '
', ' 例子 2:', '
'; 
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 '
', ' 例子 3:', '
'; 
try { 
     // 抛出自定义异常  
    throw new MyException('3 isnt allowed as a parameter', 6); 
} catch (Exception $e) {        // 捕获异常 
    echo "Default Exception caught\n", $e; 

 
// 执行后续代码 
// 例子 4 
echo '
', ' 例子 4:', '
'; 
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() 函数可设置处理所有未捕获异常的用户定义函数。 


function myException($exception) 

echo "Exception: " , $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专栏

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1250
24
PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

See all articles