# display_errors off: vypnutí chybových výstupů v produkci

> display_errors Off a další: která nastavení PHP drží chybová hlášení mimo ostrý web, co přidávají frameworky a jak zkontrolovat úniky informací.

Zdroj: https://phpsos.de/cs/blog/display-errors-produktion/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Na ostrém webu patří `display_errors = Off` do php.ini, spolu s `display_startup_errors = Off`, `log_errors = On` a chybovým logem mimo webroot. CMS a frameworky navíc musí běžet v produkčním režimu, jinak podrobnosti ukazují jejich vlastní chybové stránky. Uzamčeno pomocí `php_admin_flag` a po každé aktualizaci ověřeno, zůstávají chyby v logu místo v prohlížeči.

## Co prozradí jediné chybové hlášení

Varování v horním okraji stránky, „Fatal error“ místo přehledu objednávky: takové výstupy vypadají neškodně. Pro útočníka jsou mapou. Ukazují úplné cesty k souborům, názvy databází a tabulek, použité knihovny a často i verzi PHP.

Právě v situacích jako PHP2Shell, kdy se masivně hledají zranitelné servery, by server měl o sobě prozrazovat co nejméně. Žádnou mezeru v interpretu PHP to neuzavře, ale ztíží to každý další krok po průniku a cílené útoky na vaši aplikaci to činí namáhavějšími.

K tomu přistupuje ochrana osobních údajů. Chybová hlášení mohou obsahovat části požadavků, například e-mailové adresy z formulářů. Co se objeví v prohlížeči návštěvníka, už nemáte pod kontrolou.

## Výchozí hodnoty nejsou určeny pro produkci

Mnozí předpokládají, že PHP chyby samo skrývá. Příručka PHP říká něco jiného: vestavěná výchozí hodnota `display_errors` je 1 a `display_startup_errors` je od PHP 8.0 rovněž standardně zapnuto. Teprve dodávaná šablona `php.ini-production` obojí nastavuje na Off. Příručka označuje `display_errors` výslovně za vývojovou funkci, která by se na systémech v internetu nikdy neměla používat.

Zda váš server používá produkční šablonu, není samozřejmé. Image kontejnerů někdy startují zcela bez php.ini, hostingové panely nastavují vlastní hodnoty a po přestěhování se rádo zkopíruje vývojová šablona.

## display_errors off: přehled nastavení

Následující hodnoty jsou pro produkční servery rozumné. Konstanty jako `E_ALL` fungují jen v php.ini; v konfiguraci Apache nemají podle příručky PHP význam a je nutné je zadat jako číslo.

| Nastavení | Produkce | Účel |
|---|---|---|
| `display_errors` | `Off` | žádné chyby v prohlížeči |
| `display_startup_errors` | `Off` | žádné chyby při startu PHP ve výstupu |
| `log_errors` | `On` | zapisovat chyby do protokolu |
| `error_log` | cesta mimo webroot | vlastní logovací soubor pro každý web nebo pool |
| `error_reporting` | `E_ALL` | protokolovat všechny chyby, nezobrazovat |
| `html_errors` | `Off` | prostý text místo HTML v protokolech |
| `zend.exception_ignore_args` | `On` | žádné argumenty funkcí ve stack trace |
| `fatal_error_backtraces` | `0` do aktualizace (jen PHP 8.5) | přechodné opatření podle php.net |

`zend.exception_ignore_args` je zvlášť cenné. Bez tohoto nastavení mohou stack trace v lozích a na chybových stránkách obsahovat argumenty volání funkcí, tedy i hesla nebo tokeny, které se právě zpracovávaly.

```ini
; php.ini webového SAPI
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/website-fehler.log
error_reporting = E_ALL
html_errors = Off
zend.exception_ignore_args = On
; jen PHP 8.5, přechodné opatření do aktualizace na 8.5.12:
; fatal_error_backtraces = 0
```

V poolu FPM nejdůležitější hodnoty navíc uzamkněte, aby je žádná aplikace pomocí `ini_set()` nezapnula zpět:

```ini
; např. /etc/php/8.3/fpm/pool.d/seite1.conf
php_admin_flag[display_errors] = off
php_admin_flag[display_startup_errors] = off
php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
```

Poté restartujte příslušnou službu PHP. Jak přesně uzamykání funguje, vysvětluje článek [php_admin_value: uzamknutí nastavení proti přepsání](https://phpsos.de/cs/blog/php-admin-value-sperren/). Úplnou základní konfiguraci najdete v článku [Bezpečná konfigurace php.ini](https://phpsos.de/cs/ratgeber/php-ini-sicher-konfigurieren/).

## Druhý přepínač: ladicí režim aplikace

PHP je jen polovina práce. Moderní frameworky chyby zachytávají samy a zobrazují vlastní, často velmi podrobné chybové stránky. V ladicím režimu obsahují výňatky ze zdrojového kódu, hodnoty konfigurace a někdy i proměnné prostředí. Tyto stránky se zobrazí i tehdy, když je `display_errors` v PHP vypnuto.

Zkontrolujte proto u každé aplikace její vlastní přepínač. U WordPressu jsou to `WP_DEBUG` a `WP_DEBUG_DISPLAY` v `wp-config.php`, u Laravelu a Symfony `APP_DEBUG` a prostředí v souboru `.env`, u jiných systémů produkční režim podle dokumentace výrobce. Na ostrém systému patří ladicí režim trvale vypnout, i „jen na chvíli k testování“ je riziko.

Jak se s chybami v aplikaci zachází čistě, místo aby se potlačovaly, popisuje [Chyby a výjimky v PHP](https://phpsos.de/cs/php/fehler-und-exceptions/).

## Jak najít chybové výstupy dříve než ostatní

Jednorázové nastavení nestačí. Chybové výstupy se po aktualizacích, stěhováních nebo změnách v panelu vracejí. Pomůže krátký kontrolní postup:

1. Zkontrolovat platné hodnoty z webu, nejen z příkazové řádky, například krátce umístěným a ihned smazaným kontrolním souborem.
2. Zkontrolovat ladicí režim každé aplikace v jejím konfiguračním souboru.
3. Prohledat doručené stránky na typické texty chyb, jak ukazuje blok kódu níže.
4. Ve vyhledávači pomocí dotazu `site:` na vaši doménu hledat výrazy jako „Fatal error“ nebo „Warning“.
5. Ověřit, že se do chybového logu zapisuje a že neleží ve webrootu.

```bash
# Prohledat doručené stránky na texty chyb PHP (jen vlastní domény)
for url in https://www.example.de/ https://www.example.de/kontakt/; do
  curl -s "$url" | grep -E -o "(Fatal error|Warning|Notice|Deprecated|Stack trace)[^<]{0,80}" | head -3
done
# Zapisuje se do chybového logu?
ls -l /var/log/php/
```

> **Důležité:**
> Skrývat chyby není náhradou za jejich odstranění. Log plný varování je upozornění na potřebu údržby a po průniku je často důležitou stopou. Co při tom protokolovat a co ne, popisuje [Bezpečné logování: protokolovat chyby bez úniku dat](https://phpsos.de/cs/blog/sicher-loggen-php/).

## Závěr: tiše v prohlížeči, hovorně v logu

Pravidlo pro produkční servery je jednoduché: chyby patří do protokolu, ne na web. V praxi selhává na výchozích hodnotách, které nejsou určeny pro produkci, na ladicích přepínačích v aplikacích a na konfiguracích, které se po aktualizacích nebo stěhováních vrátí zpět.

Kdo vypne `display_errors` a `display_startup_errors`, uzamkne hodnoty v poolu, zkontroluje ladicí režim aplikace a výsledek pravidelně ověřuje, uzavře jeden z nejčastějších zdrojů zbytečného úniku informací. Pracnost je nízká, účinek vydrží, dokud kontrola zůstává součástí každé aktualizace.

Jeden bod by neměl zapadnout: chybový log není odpadkový koš. Kdo jej pravidelně čte, pozná chybné aktualizace, zastaralé funkce a někdy i první stopy útoku, dlouho před tím, než si zákazníci něčeho všimnou.

## Jak konkrétně pomáhá PHP SOS?

- **Zkontrolovat:** Načteme platná nastavení chyb pro každý web a pool a doručené stránky prohledáme na chybové výstupy.
- **Přepnout:** Nastavení PHP a aplikací nastavíme pro ostrý provoz a uzamkneme je proti přepsání.
- **Zřídit protokoly:** Chybové logy leží mimo webroot, rotují se a jsou přístupné vašim vývojářům.
- **Udržet trvale:** V rámci [smlouvy o bezpečnostní údržbě](https://phpsos.de/cs/leistungen/security-wartungsvertrag/) nastavení po každé aktualizaci znovu zkontrolujeme.


## Časté dotazy

**Není display_errors v PHP stejně vypnuto?**  
Ne automaticky. Podle příručky PHP je vestavěná výchozí hodnota display_errors 1. Teprve dodávaná šablona php.ini-production nastavuje Off. Zda váš server tuto šablonu používá, závisí na distribuci, panelu nebo image kontejneru a je třeba to ověřit.

**Stačí display_errors = Off, když WordPress nebo Laravel běží v ladicím režimu?**  
Ne. Mnoho CMS a frameworků má vlastní chybové stránky, které mohou zobrazovat podrobnosti nezávisle na PHP. Vypněte proto i ladicí režim aplikace, například WP_DEBUG_DISPLAY u WordPressu nebo APP_DEBUG u Laravelu a Symfony.

**Kam jdou chyby, když se už nezobrazují?**  
S log_errors = On je PHP zapisuje do souboru, který určuje error_log, nebo do protokolu příslušného provozního režimu, například do chybového logu Apache nebo PHP-FPM. Soubor by měl ležet mimo webroot a pravidelně se rotovat.

**Co má fatal_error_backtraces společného s PHP2Shell?**  
Nastavení existuje od PHP 8.5 a je standardně aktivní. php.net uvádí fatal_error_backtraces=0 s následným restartem jako jedno z přechodných opatření pro PHP 8.5, dokud aktualizace na 8.5.12 chybí. Aktualizaci nenahrazuje.

## Zdroje

- [Příručka PHP: zpracování a protokolování chyb](https://www.php.net/manual/en/errorfunc.configuration.php)
- [Příručka PHP: změna konfigurace (php_admin_flag)](https://www.php.net/manual/en/configuration.changes.php)
- [php.net: bezpečnostní oznámení](https://www.php.net/)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
