Exceptions
Exceptions
Innehållsförteckning
PHP har en undantagshanteringsmodell som liknar andra programmeringsspråk. Ett undantag kan utlösas och fångas i PHP. Kod kan omges med ett try-block för att underlätta hanteringen av potentiella undantag. Varje try-block måste ha minst ett motsvarande catch- eller finally-block.
Om ett undantag utlöses och dess nuvarande funktionsomfång saknar ett catch-block, kommer undantaget att "bubbla upp" i anropsstacken tills det hittar ett matchande catch-block. Alla finally-block som stöts på under denna process kommer att köras. Om anropsstacken har tagits hela vägen tillbaka till det globala omfånget utan att ett matchande catch-block hittas, kommer programmet att avslutas med ett dödligt fel om ingen global undantagshanterare har satts.
Det utlösta objektet måste vara en instans av Throwable. Att försöka kasta ett objekt som inte är det resulterar i ett PHP-dödligt fel.
Från och med PHP 8.0.0 är throw ett uttryck och kan användas i alla uttryckssammanhang. Tidigare var det ett uttalande och behövde vara på en egen rad.
catch
Ett catch-block definierar hur man ska reagera på ett utkastat undantag. Ett catch-block definierar en eller flera typer av undantag eller fel det kan hantera, samt en variabel för att tilldela undantaget. (Variabeln var nödvändig före PHP 8.0.0.) Det första catch-blocket som ett utkastat undantag eller fel möter som matchar typen av det utkastade objektet kommer att hantera objektet.
Flera catch-block kan användas för att fånga olika undantagsklasser. Normal körning (när inget undantag utlöses inom try-blocket) kommer att fortsätta efter det sista catch-blocket i följd. Undantag kan utlösas (eller återkastas) inom ett catch-block. Om inte, kommer körningen att fortsätta efter det catch-block som utlöste det.
När ett undantag utlöses kommer kod som följer uttalandet inte att köras, och PHP kommer att försöka hitta det första matchande catch-blocket. Om ett undantag inte fångas kommer ett PHP-dödligt fel att utfärdas med ett "Uncaught Exception ..." meddelande, såvida inte en hanterare har definierats med set_exception_handler().
Från och med PHP 7.1.0 kan ett catch-block specificera flera undantag med hjälp av rörtecknet (|). Detta är användbart när olika undantag från olika klasshierarkier hanteras på samma sätt.
Från och med PHP 8.0.0 är variabelnamnet för ett fångat undantag valfritt. Om inte specificerat kommer catch-blocket fortfarande att köras men kommer inte ha tillgång till det utkastade objektet.
finally
Ett finally-block kan också specificeras efter eller istället för catch-block. Kod inom finally-blocket kommer alltid att köras efter try och catch-block, oavsett om ett undantag har utlösts, och innan normal körning återupptas.
En anmärkningsvärd interaktion är mellan finally-blocket och ett return-uttalande. Om ett return-uttalande möts inuti antingen try eller catch-blocken, kommer finally-blocket fortfarande att köras. Dessutom utvärderas return-uttalandet när det möts, men resultatet returneras efter att finally-blocket har körts. Om finally-blocket också innehåller ett return-uttalande, returneras värdet från finally-blocket.
Global undantagshanterare
Om ett undantag får bubbla upp till det globala omfånget, kan det fångas av en global undantagshanterare om den är satt. Funktionen set_exception_handler() kan sätta en funktion som kommer att kallas istället för ett catch-block om inget annat block anropas. Effekten är i huvudsak densamma som om hela programmet var omslutet av ett try-catch-block med den funktionen som catch.
Noteringar
Notera:
Internt använder PHP-funktioner huvudsakligen felrapportering, endast moderna objektorienterade tillägg använder undantag. Fel kan dock enkelt översättas till undantag med ErrorException. Denna teknik fungerar dock endast med icke-dödliga fel.
Exempel #1 Omvandla felrapportering till undantag
<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
set_error_handler('exceptions_error_handler');
?>
Tips: Standard PHP Library (SPL) tillhandahåller ett bra antal inbyggda undantag.
Exempel
Exempel #2 Kasta ett undantag
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Fortsätt körningen
echo "Hello World\n";
?>
Utmatning:
0.2 Caught exception: Division by zero. Hello World
Exempel #3 Undantagshantering med ett finally-block
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "First finally.\n";
}
try {
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "Second finally.\n";
}
// Fortsätt körningen
echo "Hello World\n";
?>
Utmatning:
0.2 First finally. Caught exception: Division by zero. Second finally. Hello World
Exempel #4 Interaktion mellan finally-blocket och return
<?php
function test() {
try {
throw new Exception('foo');
} catch (Exception $e) {
return 'catch';
} finally {
return 'finally';
}
}
echo test();
?>
Utmatning:
finally
Exempel #5 Nästlade undantag
<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
// kasta om det
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
Utmatning:
string(4) "foo!"
Exempel #6 Flerfaldig undantagshantering
<?php
class MyException extends Exception { }
class MyOtherException extends Exception { }
class Test {
public function testing() {
try {
throw new MyException();
} catch (MyException | MyOtherException $e) {
var_dump(get_class($e));
}
}
}
$foo = new Test;
$foo->testing();
?>
Utmatning:
string(11) "MyException"
Exempel #7 Utelämna den fångade variabeln (PHP 8.0.0 och senare)
<?php
class SpecificException extends Exception {}
function test() {
throw new SpecificException('Oopsie');
}
try {
test();
} catch (SpecificException) {
print "A SpecificException was thrown, but we don't care about the details.";
}
?>
Exempel #8 Kasta som ett uttryck (PHP 8.0.0 och senare)
<?php
function test() {
do_something_risky() or throw new Exception('It did not work');
}
try {
test();
} catch (Exception $e) {
print $e->getMessage();
}
?>
Sidslut
Orginalhemsidan på Engelska :https://www.php.net/manual/en/language.exceptions.php
PHP Funktioner Funktionsreferens
Det här är en maskinöversättning av PHP-manualen till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på
https://www.linux.se/kontaka-linux-se/
Tack till Datorhjälp Stockholm som har sponsrat Linux.se med webserver.