English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP 基础教程

PHP 高级教程

PHP & MySQL

PHP 参考手册

PHP-Exception-Handling

在本教程中,您将学习如何在PHP中引发和捕获异常。

什么是异常

异常是表示发生某种异常事件或错误的信号。可能由于多种原因导致异常,例如,数据库连接或查询失败,您尝试访问的文件不存在等等。

PHP提供了强大的异常处理机制,使您能够以优雅的方式处理异常。与PHP的传统错误处理系统中相反,异常处理是一种用于处理错误的面向对象的方法,它提供了更具指定性和灵活性的错误报告形式。异常模型最早是在PHP 5引入的。

使用Throw 和 Try ... Catch语句

在基于异常的方法中,程序代码编写在try块中,当在try块中执行代码期间发生异常事件时,可以使用throw语句引发异常。然后由一个或多个捕获块捕获并解析它。

以下示例演示了异常处理是如何工作的:

<?php
function division($dividend, $divisor) {
    //如果除数为零,则抛出异常
    if($divisor == 0) {
        throw new Exception('Division durch Null.');
    } else {
        $quotient = $dividend / $divisor;
        echo "<p>$dividend / $divisor = $quotient</p>";
    }
}
 
try{
    division(10, 2);
    division(30, -4);
    division(15, 0);
    
    //如果抛出异常,则后续行将不会执行
    echo '<p>所有操作均成功执行。</p>';
} catch(Exception $e){
    //Handle exception
    echo "<p>Caught exception: " . $e->getMessage() . "</p>";
}
 
// Continue execution
echo "<p>Hello World!/p>";
?>

You may wonder what this code is about. Well, let's go through each part of this code one by one to better understand.

Code usage explanation

There are four basic parts in PHP's exception handling system: try, throw, catch, and Exception class. The following list describes how each part works.

  • The division() function in the example checks if the divisor is equal to zero. If so, it throws an exception using PHP's throw statement. Otherwise, this function performs division with the given numbers and displays the result.

  • Then, in the try block, the division() function is called with different parameters. If an exception is generated while executing the code in the try block, PHP will stop executing at that point and try to find the corresponding catch block. If found, the code in the catch block is executed; otherwise, a fatal error is generated.

  • The catch block usually catches exceptions thrown in the try block and creates an object (e) containing exception information. You can retrieve the error message from this object using the getMessage() method of the exception.

In PHP's Exception class, the methods getCode(), getFile(), getLine(), and getTraceAsString() are provided to generate detailed debugging information.

<?php
//关闭默认错误报告
error_reporting(0);
 
try{
    $file = "somefile.txt";
    
    //尝试打开文件
    $handle = fopen($file, "r");
    if(!$handle){
        throw new Exception("无法打开文件!", 5);
    }
    
    //尝试读取文件内容
    $content = fread($handle, filesize($file));
    if(!$content){
        throw new Exception("Could not read file!", 10);
    }
    
    //关闭文件句柄
    fclose($handle);
    
    //显示文件内容
    echo $content;
} catch(Exception $e){
    echo "<h3>Caught Exception!/h3>";
    echo "<p>Error message: " . $e->getMessage() . "</p>";    
    echo "<p>File: " . $e->getFile() . "</p>";
    echo "<p>Zeile: " . $e->getLine() . "</p>";
    echo "<p>Fehlercode: " . $e->getCode() . "</p>";
    echo "<p>Trace: " . $e->getTraceAsString() . "</p>";
}
?>

Der Konstruktor der Ausnahme kann eine Ausnahme-Nachricht und einen Ausnahme-Code akzeptieren. Obwohl die Ausnahme-Nachricht normalerweise verwendet wird, um allgemeine Informationen über den Fehler anzuzeigen, kann der Ausnahme-Code zum Kategorisieren von Fehlern verwendet werden. Später kann der bereitgestellte Ausnahme-Code über die Methode getCode() der Exception abgerufen werden.

Tipp:Ausnahmen sollten nur für den Fall von Spezialfällen verwendet werden; sie sollten nicht für die Angabe des normalen Anwendungsf flows verwendet werden, z.B. zum Springen zu einem anderen Ort im Skript. Dies kann die Leistung der Anwendung negativ beeinflussen.

Benutzerdefinierte Ausnahmen definieren

Sie können sogar einen eigenen benutzerdefinierten Ausnahmebehandlungsmechanismus definieren, um verschiedene Arten von Ausnahmen auf unterschiedliche Weise zu behandeln. Dies ermöglicht es, für jeden Ausnahme-Typ einen separaten catch-Block zu verwenden.
Sie können die Exception-Klasse erweitern, um benutzerdefinierte Ausnahmen zu definieren, da Exception die Basisklasse aller Ausnahmen ist. Eine benutzerdefinierte Ausnahme-Klasse erbt alle Eigenschaften und Methoden der PHP Exception-Klasse. Sie können auch eigene Methoden zu einer benutzerdefinierten Exception-Klasse hinzufügen. Lassen Sie uns einen Beispiel sehen:

<?php
//Erweiterung der Exception-Klasse
class EmptyEmailException extends Exception {}
class InvalidEmailException extends Exception {}
 
$email = "[email protected]";
 
try{
    //Wenn die E-Mail leer ist, wird eine Ausnahme ausgelöst
    if($email == ""){
        throw new EmptyEmailException("<p>Bitte geben Sie Ihre E-Mail-Adresse ein!</p>");
    }
    
    //Wenn die E-Mail ungültig ist, wird eine Ausnahme ausgelöst
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {           
        throw new InvalidEmailException("<p><b>$email</b> ist keine gültige E-Mail-Adresse!/p>");
    }
    
    // Wenn die E-Mail gültig ist, wird eine Erfolgsmeldung angezeigt
    echo "<p>成功:电子邮件验证成功.</p>";
catch(EmptyEmailException $e){
    echo $e->getMessage();
catch(InvalidEmailException $e){
    echo $e->getMessage();
}
?>

In dem obigen Beispiel haben wir zwei neue Ausnahmen aus der Basisklasse Exception abgeleitet:EmptyEmailExceptionundInvalidEmailException. Mehrere Catch-Blöcke werden verwendet, um unterschiedliche Fehlermeldungen anzuzeigen, abhängig vom generierten Ausnahme-Typ.

Da diese benutzerdefinierten Ausnahmen die Eigenschaften und Methoden der Exception-Klasse erben, können wir die Methoden der Ausnahme, wie getMessage(), getLine(), getFile() und andere, verwenden, um Fehlerinformationen des Ausnahmeobjekts abzurufen.

Globale Ausnahmebehandlung einrichten

Wie in diesem Kapitel bereits diskutiert, erzeugt PHP eine kritische Fehlermeldung, wenn keine Ausnahme erfasst wird, und enthält eine Nachricht wie "Ungefangene Exception ...". Diese Fehlermeldung kann sensible Informationen enthalten, wie z.B. den Dateinamen und die Zeilennummer des Problems. Wenn Sie solche Informationen nicht dem Benutzer öffentlich machen möchten, können Sie eine benutzerdefinierte Funktion erstellen und diese Funktion an set_exception_handler() anmelden, um alle ungefangenen Ausnahmen zu behandeln.

<?php
function handleUncaughtException($e){
    //Allgemeine Fehlermeldung an den Benutzer anzeigen
    echo "Oh nein! Es ist ein Problem aufgetreten. Bitte versuchen Sie es noch einmal, falls das Problem weiterhin besteht, kontaktieren Sie uns bitte.";
    
    // Fehlerstring konstruieren
    $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - ");
    $error .= $e->getMessage() . " in file " . $e->getFile() . " on line " . $e->getLine() . "\n";
    
    //Details der Fehlermeldungen im Datei speichern
    error_log($error, 3, "var/log/exceptionLog.log");
}
 
//Registrierung eines benutzerdefinierten Ausnahmebehandlers
set_exception_handler("handleUncaughtException");
 
// Ausnahme werfen
throw new Exception("Testing Exception!");
?>

Hinweis:Ungefangene Ausnahmen führen immer zum Abbruch des Skripts. Daher muss jeder try-Block mindestens einen entsprechenden catch-Block haben, wenn das Skript nach dem Auftreten einer Ausnahme weiterlaufen soll.