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

PHP异常处理

In questo tutorial, imparerai come sollevare e catturare eccezioni in PHP.

Cos'è un'eccezione

eccezioni sono segnali che rappresentano l'insorgere di un qualche evento anormale o errore. Le eccezioni possono verificarsi per molte ragioni, come, ad esempio, il fallimento della connessione o della query del database, il file che stai cercando di accedere non esiste, ecc.

PHP fornisce un potente meccanismo di gestione delle eccezioni che ti permette di gestire le eccezioni in modo elegante. A differenza del tradizionalegestione degli errorisistema, al contrario, la gestione delle eccezioni è un metodo per gestire gli erroriorientato agli oggettimetodo, che offre una forma di report di errori più specifica e flessibile. Il modello di eccezione è stato introdotto per la prima volta in PHP 5.

Utilizzo di Throw e Try ... Catch

Nel metodo basato su eccezioni, il codice del programma viene scritto nel blocco try, quando durante l'esecuzione del codice nel blocco try si verifica un evento di eccezione, si può usare la frase throw per sollevare un'eccezione. Poi viene catturata e analizzata da uno o più blocchi catch.

Esempio di come funziona la gestione delle eccezioni:

<?php
function division($dividend, $divisor) {
    // Se il divisore è zero, viene lanciata un'eccezione
    if($divisor == 0) {
        throw new Exception('Divisione per zero.');
    } else {
        $quotient = $dividend / $divisor;
        echo "<p>$dividend / $divisor = $quotient</p>";
    }
}
 
try{
    division(10, 2);
    division(30, -4);
    division(15, 0);
    
    // Se viene lanciata un'eccezione, le righe successive non verranno eseguite
    echo '<p>Tutti i comandi sono stati eseguiti con successo.</p>';
}
    // Gestione dell'eccezione
    echo "<p>Eccezione catturata: " . $e->getMessage() . "</p>";
}
 
// Continua l'esecuzione
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.

Explanation of code usage

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

  • 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 the PHP Exception class, there are also methods such as getCode(), getFile(), getLine(), and getTraceAsString() that can be used 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;
}
    echo "<h3>Caught Exception!</h3>";
    echo "<p>Error message: \" . $e->getMessage() . "</p>";    
    echo "<p>File: \" . $e->getFile() . "</p>";
    echo "<p>Line: \" . $e->getLine() . "</p>";
    echo "<p>Codice di errore: " . $e->getCode() . "</p>";
    echo "<p>Trace: " . $e->getTraceAsString() . "</p>";
}
?>

Il costruttore dell'eccezione può accettare un messaggio di eccezione e un codice di eccezione. Sebbene il messaggio di eccezione sia solitamente utilizzato per mostrare informazioni generali sulla causa dell'errore, il codice di eccezione può essere utilizzato per classificare gli errori. Successivamente, il codice di eccezione fornito può essere recuperato tramite il metodo getCode() di Exception.

Suggerimento:Le eccezioni sono applicate solo per rappresentare situazioni speciali; non dovrebbero essere utilizzate per specificare il flusso normale dell'applicazione, come saltare a un altro punto dello script. Questo potrebbe influenzare negativamente le prestazioni dell'applicazione.

Definire eccezioni personalizzate

Puoi anche definire un gestore di eccezioni personalizzato per gestire diversi tipi di eccezioni in modi diversi. Questo permette di utilizzare un blocco catch separato per ogni tipo di eccezione.
Puoi estendere la classe Exception per definire eccezioni personalizzate, poiché Exception è la classe base di tutte le eccezioni. Le classi di eccezione personalizzate ereditano tutte le proprietà e i metodi della classe Exception di PHP. Puoi anche aggiungere metodi personalizzati alla classe di eccezione personalizzata. Vediamo alcuni esempi di seguito:

<?php
// Estende la classe Exception
class EmptyEmailException extends Exception {}
class InvalidEmailException extends Exception {}
 
$email = "[email protected]";
 
try{
    // Se l'email è vuota, lancia un'eccezione
    if($email == "") {
        throw new EmptyEmailException("<p>Inserisci il tuo indirizzo email!</p>");
    }
    
    // Se l'email non è valida, lancia un'eccezione
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {           
        throw new InvalidEmailException("<p><b>$email</b> non è un indirizzo email valido!</p>");
    }
    
    // Se l'email è valida, visualizza un messaggio di successo
    echo "<p>Successo: Verifica dell'email completata con successo.</p>";
catch(EmptyEmailException $e){
    echo $e->getMessage();
catch(InvalidEmailException $e){
    echo $e->getMessage();
}
?>

Nell'esempio sopra, abbiamo derivato due nuove classi di eccezioni dal tipo di base Exception:EmptyEmailExceptioneInvalidEmailException. Più blocchi di cattura possono essere utilizzati per mostrare messaggi di errore diversi a seconda del tipo di eccezione generata.

Poiché queste classi di eccezioni personalizzate ereditano le proprietà e i metodi della classe Exception, possiamo utilizzare i metodi di classe delle eccezioni, come getMessage(), getLine(), getFile(), ecc., per recuperare le informazioni di errore dell'oggetto di eccezione.

Impostare il gestore di eccezioni globale

Come discusso in questo capitolo, se non viene catturata un'eccezione, PHP genera un errore fatale con il messaggio "Uncaught Exception ...". Questo messaggio di errore potrebbe contenere informazioni sensibili, come il nome del file e il numero di riga in cui è stato rilevato il problema. Se non si desidera rendere queste informazioni pubbliche agli utenti, è possibile creare una funzione personalizzata e registrarla come gestore di eccezioni non catturate utilizzando set_exception_handler().

<?php
function handleUncaughtException($e){
    // Mostrare un messaggio di errore generico all'utente
    echo "Oh no! Si è verificato un problema. Riprovare, se il problema persiste, contattarci.";
    
    // Costruire la stringa di errore
    $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - ");
    $error .= $e->getMessage() . " in file " . $e->getFile() . " sulla riga " . $e->getLine() . "\n";
    
    // Registrare i dettagli dell'errore nel file
    error_log($error, 3, "var/log/exceptionLog.log");
}
 
// Registrare il gestore di eccezioni personalizzato
set_exception_handler("handleUncaughtException");
 
// Lanciare eccezione
throw new Exception("Testing Exception!");
?>

Attenzione:Non catturati eccezioni causano sempre la terminazione dello script. Pertanto, se si desidera che lo script continui a eseguire dopo il punto di eccezione, ogni blocco try deve avere almeno un blocco catch corrispondente.