Nowości, zmiany i nowe funkcje w PHP 5.5 – cz.3: Support for finally in try/catch blocks

Najnowsza wersja języka PHP (czyli 5.5) wprowadza kilka bardzo ciekawych, nowych funkcjonalności. Są nimi:

W trzeciej części przedstawiam kolejną nową funkcjonalność – blok finally przy przechwytywaniu wyjątków.

W najprostszym wypadku schemat przechwytywania wyjątków wygląda tak:

try {
    throw new Exception();
}
catch( Exception $e ) {
    echo $e->getMessage();
}

Można również przechwytywać osobno różne typy wyjątków.

class FirstException extends Exception {}
class SecondException extends Exception {}
 
try {
    if( $t == 1 ) {
        throw new FistException();
    }
    else if( $t == 2 ) {
        throw new SecondException();
    }
}
catch( FistException $e ) {
    echo "First";
}
catch( SecondException $e ) {
    echo "Second";
}

Nie można natomiast łączyć obsługi wyjątków w łańcuchy. W poniższym kodzie wykona się tylko pierwszy catch.

try {
    throw new FirstException();
}
catch( FirstException $e ) {
    echo 'FirstException';
}
catch( Exception $e ) {
    echo 'Exception';
}

Można jednakże zasymulować łańcuchowe przechwytywanie wyjątków poprzez zagnieżdżenia i ponowne podnoszenie wyjątków. Te rozwiązanie jest jednakże trochę nieestetyczne.

try {
    try {
        throw new FirstException();
    }
    catch( FirstException $e ) {
        echo 'FirstException' . PHP_EOL;
        throw $e;
    }
}
catch( Exception $e ) {
    echo 'Exception' . PHP_EOL;
}

Począwszy od PHP w wersji 5.5.0, zostaje wprowadzony blok finally, który daje kolejny rodzaj przepływu sterowania w blokach try/catch.

try {
    throw new FirstException();
}
catch( FirstException $e ) {
    echo 'FirstException' . PHP_EOL;
}
finally {
    echo 'Finally' . PHP_EOL;
}

Blok finally wykonuje się zawsze po blokach try/catch:

  • niezależnie od tego, czy wyjątek został podniesiony
  • niezależnie od tego, czy wyjątek został przechwycony