0Pricing
PHP Academy · Lekcja

Tworzenie własnych wyjątków

Rozszerzaj klasę Exception, aby tworzyć typy błędów specyficzne dla domeny

Tworzenie własnych wyjątków to bezpłatna lekcja PHP Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej PHP Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs PHP Academy zawiera 4 lekcji w sumie.

Dlaczego warto tworzyć własne wyjątki?

Niestandardowe wyjątki pozwalają:

  • Odróżniać błędy aplikacji od ogólnych błędów PHP
  • Przechowywać dane specyficzne dla domeny (identyfikator zamówienia, identyfikator użytkownika itp.)
  • Przechwytywać określone typy błędów na różnych warstwach
  • Tworzyć znaczące i samodokumentujące się hierarchie błędów

Rozszerzanie Exception

Niestandardowy wyjątek utwórz, rozszerzając bazową klasę Exception:

<?php
class ValidationException extends \Exception
{
    private array $errors;

    public function __construct(array $errors, string $message = '', int $code = 0)
    {
        $this->errors = $errors;
        parent::__construct($message ?: implode(', ', $errors), $code);
    }

    public function getErrors(): array
    {
        return $this->errors;
    }
}

Używanie niestandardowego wyjątku

Zgłaszaj i przechwytuj własny wyjątek:

<?php
function createUser(array $data): void {
    $errors = [];
    if (empty($data['email'])) $errors[] = 'Email required';
    if (empty($data['name']))  $errors[] = 'Name required';

    if ($errors) {
        throw new ValidationException($errors);
    }
    // save user...
}

try {
    createUser([]);
} catch (ValidationException $e) {
    foreach ($e->getErrors() as $err) {
        echo '- ' . $err . PHP_EOL;
    }
}

Projektowanie hierarchii wyjątków

Zaprojektuj hierarchię dla swojej domeny:

<?php
// Base exception for your app
class AppException extends \RuntimeException {}

// Domain-specific exceptions
class NotFoundException extends AppException {}
class AuthException extends AppException {}
class PaymentException extends AppException {}

// Specific payment errors
class InsufficientFundsException extends PaymentException {
    public function __construct(public readonly float $balance, public readonly float $required) {
        parent::__construct("Insufficient funds: have $balance, need $required");
    }
}

Przechwytywanie według hierarchii

Przechwyć klasę bazową, aby obsłużyć wszystkie wyjątki pochodne:

<?php
try {
    processPayment($order);
} catch (InsufficientFundsException $e) {
    echo 'Low balance: need ' . $e->required;
} catch (PaymentException $e) {
    echo 'Payment failed: ' . $e->getMessage();
} catch (AppException $e) {
    echo 'App error: ' . $e->getMessage();
} catch (\Throwable $e) {
    // Last resort
    error_log($e);
}

Dodawanie kontekstu do wyjątków

Wzbogać wyjątki o dodatkowe dane ułatwiające debugowanie:

<?php
class HttpException extends \RuntimeException
{
    public function __construct(
        private int    $statusCode,
        string         $message = '',
        ?\Throwable    $previous = null
    ) {
        parent::__construct($message, $statusCode, $previous);
    }

    public function getStatusCode(): int
    {
        return $this->statusCode;
    }
}

Przykład wyjątku HTTP

Używanie wyjątku HTTP w aplikacji internetowej:

<?php
try {
    $user = findUserById($id);
    if (!$user) throw new HttpException(404, 'User not found');
    if (!$user->canAccess($resource)) {
        throw new HttpException(403, 'Access denied');
    }
} catch (HttpException $e) {
    http_response_code($e->getStatusCode());
    echo json_encode(['error' => $e->getMessage()]);
}

Wyjątki oparte na interfejsach

Używaj interfejsów do grupowania niezwiązanych ze sobą klas wyjątków:

<?php
interface UserFacingException
{
    public function getUserMessage(): string;
}

class ValidationException extends \Exception implements UserFacingException
{
    public function getUserMessage(): string
    {
        return 'Please check your input: ' . $this->getMessage();
    }
}

// In controller:
catch (UserFacingException $e) {
    echo $e->getUserMessage();
}

Wzorzec nazwanych konstruktorów

Używaj statycznych metod fabrykujących dla typowych scenariuszy wyjątków:

<?php
class OrderException extends \RuntimeException
{
    public static function notFound(int $id): self
    {
        return new self("Order #$id not found", 404);
    }

    public static function alreadyShipped(int $id): self
    {
        return new self("Order #$id already shipped", 409);
    }
}

throw OrderException::notFound($orderId);

Serializowanie wyjątków

Konwertuj dane wyjątku na tablicę na potrzeby rejestrowania lub odpowiedzi API:

<?php
function exceptionToArray(\Throwable $e): array {
    return [
        'type'    => get_class($e),
        'message' => $e->getMessage(),
        'code'    => $e->getCode(),
        'file'    => $e->getFile(),
        'line'    => $e->getLine(),
        'trace'   => $e->getTraceAsString(),
        'previous' => $e->getPrevious()
            ? exceptionToArray($e->getPrevious())
            : null,
    ];
}

Dobre praktyki dotyczące niestandardowych wyjątków

Wskazówki dotyczące projektowania niestandardowych wyjątków:

  • Rozszerzaj RuntimeException w przypadku nieoczekiwanych sytuacji
  • Rozszerzaj LogicException w przypadku błędów programisty (nieprawidłowych argumentów)
  • Nie twórz osobnej klasy wyjątku dla każdego możliwego komunikatu — zamiast tego używaj kodów
  • Nazwy klas wyjątków zapisuj w PascalCase i kończ słowem Exception
  • Dokumentuj, jakie wyjątki może zgłaszać każda metoda

Szybki test

Jaką bazową klasę PHP należy rozszerzyć, aby utworzyć niestandardowy wyjątek reprezentujący błąd logiczny w kodzie?

Podsumowanie: niestandardowe wyjątki

Podsumowanie informacji o niestandardowych wyjątkach:

  • Rozszerzaj Exception lub jedną z jej klas pochodnych
  • Dodawaj właściwości i metody specyficzne dla domeny
  • Projektuj hierarchie — przechwycenie klasy nadrzędnej obejmuje wszystkie klasy potomne
  • Używaj interfejsów do grupowania niezwiązanych ze sobą wyjątków
  • Stosuj statyczne nazwane konstruktory, aby zwiększyć czytelność
  • Zawsze wywołuj parent::__construct()

Często zadawane pytania

Czy lekcja „Tworzenie własnych wyjątków” jest bezpłatna?

Tak — pełny tekst „Tworzenie własnych wyjątków” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu PHP Academy, przejdź na CoddyKit PRO. Kurs PHP Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Tworzenie własnych wyjątków”?

Rozszerzaj klasę Exception, aby tworzyć typy błędów specyficzne dla domeny Ćwiczysz PHP Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć PHP Academy?

Nie wymagamy żadnego doświadczenia. PHP Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Tworzenie własnych wyjątków”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji PHP Academy?

Tak. Każda lekcja PHP Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Typy błędów PHP i raportowanie
  2. Try, catch i finally
  3. Tworzenie własnych wyjątków
  4. Rejestrowanie błędów i dobre praktyki
← Powrót do PHP Academy