Podstawy exception handling w PHP – pisanie własnych Errorów, rzucanie i łapanie ich oraz obsługa. Do dzieła.
Piszemy customowy exception bazując na najbardziej ogólnej klasie:
class ContainerException extends Exception
{
}
Teraz funkcja, która może wyrzucić exception (ta zawsze wyrzuca):
function _next($className = 'FakeCls', $name = 'FakeParam'){
throw new ContainerException("Failed to resolve class {$className} because param {$name} is missing a type hint.");
}
Teraz obsługa poprzez blok try-catch:
try {
_next();
} catch (ContainerException $e) {
echo $e->getMessage();
}
//Failed to resolve class FakeCls because param FakeParam is missing a type hint.
Teraz ValidationException, czyli coś, co może być rzucone podczas run-time:
class ValidationException extends RuntimeException
{
public function __construct(public array $errors, int $code = 422)
{
parent::__construct(code: $code);
}
}
Jak widać zarówno promocja przez konstruktor jak i „tradycyjne” wołanie konstruktora a nawet konstruktora-rodzica.
Teraz nasza pseudo-funkcja:
function _next(){
$errors = [
'name' => 'Must be uniqe!',
'email' => 'Email already taken!',
'password' => 'Must be at least 8 characters long!'
];
if (count($errors)) {
throw new ValidationException($errors);
}
}
Próbujemy wywołać _next, jeżeli error, to zapisujemy errory do sesji (plus wyświetlamy je):
try {
_next();
} catch (ValidationException $e) {
$_SESSION['errors'] = $e->errors;
print_r($_SESSION['errors']);
}
// Array (
// [name] => Must be uniqe!
// [email] => Email already taken!
// [password] => Must be at least 8 characters long!
// )
Może się wydawać, że obsługa błędów jest łatwa, ale nic z tych rzeczy – są własne error-handlery i exception-handlery, łatwe to to może wydawać się przedstawione w ten sposób.
Tym niemniej są to podstawy, które w wielu przypadkach całkowicie wystarczą.