Menu
Coddy logo textTech

Try, Catch, Finally

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 68 di 91.

Ora che sai come creare e generare eccezioni, devi imparare a intercettarle. La struttura try-catch-finally ti permette di gestire le eccezioni in modo corretto, invece di lasciare che mandino in crash la tua applicazione.

Racchiudi il codice che potrebbe generare un'eccezione in un blocco try, quindi gestisci l'eccezione in un blocco catch:

<?php
class Calculator {
    public function divide(int $a, int $b): float {
        if ($b === 0) {
            throw new InvalidArgumentException("Cannot divide by zero");
        }
        return $a / $b;
    }
}

$calc = new Calculator();

try {
    echo $calc->divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo "Error: " . $e->getMessage();
}

Output:

Error: Cannot divide by zero

Puoi intercettare diversi tipi di eccezioni con più blocchi catch. PHP li controlla in ordine, quindi inserisci prima le eccezioni più specifiche:

<?php
try {
    // codice rischioso
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

Il blocco finally viene eseguito indipendentemente dal fatto che sia stata generata o intercettata un'eccezione. È perfetto per le attività di pulizia, come chiudere le connessioni:

<?php
try {
    echo "Attempting operation\n";
    throw new Exception("Failed");
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";
} finally {
    echo "Cleanup complete";
}

Output:

Attempting operation
Caught: Failed
Cleanup complete

Il blocco finally viene eseguito anche se restituisci un valore dall'interno dei blocchi try o catch, rendendolo affidabile per le operazioni di pulizia essenziali.

challenge icon

Sfida

Facile

Costruiamo un sistema di elaborazione dei file che mostri come try-catch-finally collaborano per gestire gli errori in modo appropriato, assicurandosi che la pulizia venga sempre eseguita.

Organizzerai il codice in tre file:

  • FileException.php: crea una classe personalizzata FileException che estende Exception. Rappresenterà gli errori relativi ai file nel tuo sistema.
  • FileProcessor.php: crea una classe FileProcessor che simula le operazioni sui file. Includi il file FileException. La tua classe deve avere:
    • Una proprietà booleana privata $isOpen inizializzata a false
    • Un metodo open(string $filename): void che imposta $isOpen su true e stampa "Opening: [filename]". Se il nome del file è "invalid.txt", lancia una FileException con il messaggio "Cannot open file"
    • Un metodo process(): void che stampa "Processing file...". Se $isOpen è false, lancia una RuntimeException con il messaggio "File not open"
    • Un metodo close(): void che imposta $isOpen su false e stampa "File closed"
    • Un metodo isOpen(): bool che restituisce lo stato corrente
  • main.php: includi il file FileProcessor. Riceverai un input: un nome di file.

    Crea un FileProcessor e usa una struttura try-catch-finally per:

    • Nel blocco try: chiama open() con il nome del file, quindi chiama process()
    • Gestisci prima FileException e stampa "File error: [message]"
    • Gestisci RuntimeException e stampa "Runtime error: [message]"
    • Nel blocco finally: controlla se il file è aperto usando isOpen() e, in caso affermativo, chiama close(). Poi stampa "Cleanup complete"

Il blocco finally assicura che la pulizia venga eseguita sia in caso di successo sia in caso di errore delle operazioni. Questo schema è essenziale per gestire risorse come file, connessioni al database o socket di rete, per le quali la pulizia deve avvenire indipendentemente da ciò che succede durante l'elaborazione.

Provalo tu

<?php
require_once 'FileProcessor.php';

// Leggi l'input
$filename = trim(fgets(STDIN));

// TODO: Crea un'istanza di FileProcessor

// TODO: Usa la struttura try-catch-finally:
// - Nel blocco try: chiama open() con il nome del file, poi chiama process()
// - Intercetta prima FileException e stampa "File error: [message]"
// - Intercetta RuntimeException e stampa "Runtime error: [message]"
// - Nel blocco finally: verifica se il file è aperto usando isOpen(); in tal caso, chiama close()
//   Poi stampa "Cleanup complete"

?>
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online