# Hibák és kivételek (exceptions) a PHP-ban

> Hibák és kivételek a PHP-ban: Throwable, Error és Exception, try/catch/finally, globális kezelők, valamint biztonságos hibakimenet- és naplóbeállítások.

Forrás: https://phpsos.de/hu/php/fehler-und-exceptions/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** A PHP két úton jelzi a problémákat: klasszikus hibaként, például figyelmeztetésként és megjegyzésként, amelyeket az `error_reporting` vezérel, valamint kivételként, amelyeket `try` és `catch` segítségével lehet elkapni. A PHP 7 óta sok belső hiba is `Error` osztályú objektumot dob; ez az `Exception`-nel együtt a `Throwable` interfészt valósítja meg. Éles üzemben az a szabály, hogy a hibákat naplózni kell, és soha nem szabad a böngészőben megjeleníteni. A PHP 8.5-ön a PHP2Shell miatt az átmeneti intézkedésekhez a `fatal_error_backtraces=0` is hozzátartozik.

## Két világ: klasszikus hibák és kivételek

A PHP olyan korból származik, amikor a hibákat főleg üzenetként írták ki: megjegyzések (`E_NOTICE`), figyelmeztetések (`E_WARNING`), elavult függvények (`E_DEPRECATED`) és végzetes hibák (`E_ERROR`). Ezen üzenetek közül sok futni hagyja a szkriptet, gyakran hibás vagy üres adatokkal.

A kivételek másként működnek. Megszakítják a normál lefutást, és a következő megfelelő `catch` blokkra ugranak. Ha egyet sem találnak, a szkript véget ér. A döntéshozók számára a különbség azért fontos, mert egy csendes figyelmeztetés oda vezethet, hogy egy rendelés hiányosan mentődik el anélkül, hogy bárki észrevenné. A kivétel láthatóvá és kezelhetővé teszi a problémát.

A klasszikus üzenetek alulértékelt haszna az `E_DEPRECATED` típusú megjegyzések. Ezek jelzik, hogy egy nyelvi eszköz egy jövőbeli PHP-verzióban megszűnik. Aki a naplóban gyűjti, és rendszeresen kiértékeli őket, egy frissítés előtt tudja, mely helyeket kell módosítani, és sürgős biztonsági rés esetén nem kell hosszan tesztelnie.

## A Throwable-hierarchia

Minden, ami `throw`-val dobható és `catch`-csel elkapható, megvalósítja a `Throwable`-t. Alatta két ág van:

| Osztály | Cél | Példák az alosztályokra |
|---|---|---|
| `Exception` | az alkalmazás és a bővítmények várható hibái | `ErrorException`, `PDOException`, saját osztályok |
| `Error` | a PHP belső hibái | `TypeError`, `ValueError`, `ArgumentCountError`, `ArithmeticError`, `DivisionByZeroError`, `UnhandledMatchError` |

A saját hibaosztályok az `Exception`-ből származnak, nem az `Error`-ból. A PHP 8.0 óta a legtöbb belső függvény érvénytelen paraméter esetén `TypeError`t vagy `ValueError`t dob, ahelyett hogy csak figyelmeztetést írna ki. A `strlen([])` ilyen eset.

## try, catch és finally a gyakorlatban

```php
<?php
declare(strict_types=1);

final class ZahlungFehlgeschlagen extends RuntimeException {}

function bezahlen(Bestellung $b, Zahlungsdienst $dienst, LoggerInterface $log): bool
{
    try {
        $dienst->belasten($b->betrag(), $b->referenz());
        return true;
    } catch (ZahlungFehlgeschlagen $e) {
        $log->warning('Zahlung abgelehnt', ['bestellung' => $b->id(), 'exception' => $e]);
        return false;
    } catch (TimeoutException | VerbindungsFehler) {
        // a PHP 8.0 óta a változó a catch-ben elhagyható
        $log->error('Zahlungsdienst nicht erreichbar', ['bestellung' => $b->id()]);
        return false;
    } finally {
        $dienst->verbindungSchliessen();
    }
}
```

Több osztály a `|` jellel összevonható egyetlen `catch`-ben. A `finally` blokk mindig lefut, akár történt hiba, akár nem. A PHP 8.0 óta a `throw` kifejezés is, így például a `??` mögé kerülhet: `$id = $_GET['id'] ?? throw new InvalidArgumentException('id fehlt');`.

## Globális kezelők: set_error_handler és set_exception_handler

Két függvény fogja el azt, ami egyébként átcsúszna. A `set_exception_handler()` egy függvényt regisztrál az el nem kapott Throwable-ökhöz. A kézikönyv szerint a szkript a meghívása után véget ér; naplózásra és semleges hibaoldalra alkalmas tehát, nem a továbbfutásra.

Bevált megoldás az a kezelő, amely a teljes hibát időponttal és véletlenszerű azonosítóval a naplóba írja, a látogatónak pedig csak egy semleges oldalt mutat ezzel az azonosítóval. Az ügyfélszolgálat így megtalálja az esetet a naplóban, anélkül hogy belső részletek kiszivárognának.

A `set_error_handler()` a klasszikus hibákat fogja el. A kézikönyv megmutatja, hogyan lehet őket `ErrorException`-né alakítani, hogy a figyelmeztetéseket kivételként kezeljék:

```php
<?php
set_error_handler(function (int $nr, string $text, string $datei, int $zeile): bool {
    if (!(error_reporting() & $nr)) {
        return false; // az error_reporting kizárta
    }
    if ($nr === E_DEPRECATED || $nr === E_USER_DEPRECATED) {
        return false; // az elavultságra utaló megjegyzéseket nem eszkaláljuk
    }
    throw new ErrorException($text, 0, $nr, $datei, $zeile);
});
```

A végzetes hibák, például a memóriatúlcsordulás, ezen az úton nem foghatók el. Hogy mi történik túlcsordulás esetén belül, azt a [memory_limit és Out-of-Memory](https://phpsos.de/hu/php/out-of-memory/) oldal magyarázza.

## A hibakimenet és a naplózás beállítása

A legfontosabb beállítások a kézikönyv szerinti alapértékekkel:

| Beállítás | Alapérték | Ajánlás éles üzemre |
|---|---|---|
| `error_reporting` | `E_ALL` a PHP 8.0.0 óta | `E_ALL` |
| `display_errors` | `1` | `Off` |
| `display_startup_errors` | `1` a PHP 8.0.0 óta | `Off` |
| `log_errors` | `0` | `On` |
| `error_log` | üres (a webszerver, illetve a SAPI naplója) | saját fájl a webgyökéren kívül |
| `fatal_error_backtraces` | `1`, újdonság a PHP 8.5.0-ban | átmenetileg `0` (PHP2Shell) |

A PHP 8.2.0 óta az `error_log_mode` határozza meg a naplófájl fájljogosultságait, alapértelmezés szerint `0644`. Ha a naplók személyes adatokat vagy útvonalakat tartalmaznak, szigorúbb érték az ésszerű, hogy a szerver más felhasználói ne olvashassák őket. Az `ignore_repeated_errors` segítségével az azonos fájlból és sorból származó azonos üzenetek összevonhatók, hogy egy hibaciklus ne árassza el a naplót.

A mellékelt `php.ini-production` a `display_errors` értékét már `Off`-ra állítja. A kézikönyv szerint az `ini_set('display_errors', ...)` futásidőben nem hat a végzetes hibákra, a szintaktikai hibák pedig azelőtt lépnek fel, hogy bármely `ini_set()` egyáltalán lefutna. Ezeknek az értékeknek ezért a szerverkonfigurációba kell kerülniük. A háttérről a [Hibakimenet kikapcsolása éles üzemben](https://phpsos.de/hu/blog/display-errors-produktion/) cikk, a naplóvezetésről adatszivárgás nélkül a [Biztonságos naplózás](https://phpsos.de/hu/blog/sicher-loggen-php/) cikk szól.

## Hibakezelés és PHP2Shell

A PHP 8.5-höz a php.net a PHP2Shell elleni egyik átmeneti intézkedésként azt nevezi meg, hogy a `fatal_error_backtraces=0` értéket kell beállítani, majd újra kell indítani a PHP-t. A többi intézkedés a `memory_limit`-et, a `post_max_size`-t és a `session.upload_progress.enabled`-et érinti. Egyik sem helyettesíti a frissítést a PHP 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra.

```ini
; csak PHP 8.5, a php.ini-ben vagy az FPM-poolban, utána minden workert újra kell indítani
fatal_error_backtraces = 0
```

A hibanaplók a PHP2Shell után emellett fontos bizonyítékot jelentenek. Ha 2026. október 20-tól szaporodnak a memóriahibák vagy a megszakadt workerek, az támadási kísérletekre utalhat, de ártalmatlan okai is lehetnek. Őrizze meg a naplókat, és a hozzáférési naplókkal együtt értékelje ki őket, ahogyan a [Webszerver-naplók kiértékelése támadás után](https://phpsos.de/hu/ratgeber/logfiles-auswerten/) útmutató leírja.

## Hogyan segít konkrétan a PHP SOS?

- Weboldalanként megvizsgáljuk a hibakimenet és a naplózás érvényes beállításait, és éles üzemre alkalmasan állítjuk be őket.
- A PHP2Shell átmeneti intézkedéseit a PHP-verzióhoz illeszkedően alkalmazzuk, és újraindítjuk az összes workert.
- Biztosítjuk a hiba- és hozzáférési naplókat 2026. október 20-tól, és kiértékeljük őket feltűnő jelenségek szempontjából.
- A [biztonsági monitoring](https://phpsos.de/hu/leistungen/security-monitoring/) keretében jelezzük a szokatlan hibahalmozódásokat, ahelyett hogy elmerülnének a naplóban.


## Gyakori kérdések

**Mi a különbség az Error és az Exception között?**  
Mindkettő megvalósítja a Throwable interfészt. Az Exception olyan hibákra szolgál, amelyeket egy alkalmazás számít és kezel, például egy sikertelen adatbázis-kapcsolat. Az Error a PHP belső hibáit jelöli, például a TypeErrort vagy a nullával osztást.

**Legyen bekapcsolva a display_errors éles üzemben?**  
Nem. A böngészőben megjelenő hibaüzenetek elárulják az útvonalakat, a lekérdezéseket, olykor a hozzáférési adatokat is. Éles üzemben a display_errors legyen Off, a log_errors pedig On, hogy a hibák a naplóba kerüljenek, ne a látogatóhoz.

**Elkapható a memóriatúlcsordulás try/catch-csel?**  
Nem. Ha egy szkript túllépi a memory_limit-et, a PHP végzetes hibával leállítja, amely nem kapható el kivételként. Csak a hibanaplóban jelenik meg, feltéve, hogy a log_errors aktív.

**Mi a fatal_error_backtraces?**  
Egy beállítás, amely a PHP 8.5.0 óta létezik, és a végzetes hibákhoz backtrace-t fűz. Alapértelmezés szerint aktív. A PHP2Shell elleni átmeneti intézkedésként a php.net a PHP 8.5-nél azt nevezi meg, hogy 0-ra kell állítani, majd újra kell indítani a PHP-t.

## Források

- [PHP-kézikönyv: A hibakezelés konfigurációja](https://www.php.net/manual/de/errorfunc.configuration.php)
- [PHP-kézikönyv: Az Error osztály](https://www.php.net/manual/de/class.error.php)
- [PHP-kézikönyv: ErrorException](https://www.php.net/manual/en/class.errorexception.php)
- [PHP-kézikönyv: set_exception_handler](https://www.php.net/manual/en/function.set-exception-handler.php)
- [php.net: Biztonsági közlemények](https://www.php.net/)
