Na navigaci | Klávesové zkratky

Jak napsat error handler v PHP?

Pokud píšete vlastní error handler pro PHP, je bezpodmínečně nutné dodržet několik pravidel. Jinak může nabourat chování dalších knihoven a aplikací, které nečekají v error handleru zradu.

Parametry

Signatura handleru vypadá takto:

function errorHandler(
	int $severity,
	string $message,
	string $file,
	int $line,
	array $context = null // pouze v PHP < 8
): ?bool {
	...
}

Parametr $severity obsahuje úroveň chyby (E_NOTICE, E_WARNING, …). Pomocí handleru nelze zachytávat fatální chyby, jako třeba E_ERROR, takže těchto hodnot nikdy nebude parametr nabývat. Naštěstí fatální chyby v podstatě z PHP zmizely a byly nahrazeny za výjimky.

Parametr $message je chybová hláška. Pokud je zapnutá direktiva html_errors, jsou speciální znaky jako < apod. zapsány jako HTML entity, takže do podoby plain textu je musíte dekódovat. Ovšem pozor, některé znaky jako entity zapsány nejsou, což je bug. Samotné zobrazování chyb v čistém PHP je tak náchylné na XSS.

Parametry $file a $line představují název souboru a řádek, kde k chybě došlo. Pokud chyba nastala uvnitř eval(), bude $file doplněný o tuto informaci.

A nakonec parametr $context obsahuje pole lokálních proměnných, což představuje pro debugování užitečnou informaci, ale od PHP 8 je zrušený. Pokud má handler fungovat v PHP 8, parametr vynechte nebo mu dejte výchozí hodnotu.

Návratová hodnota

Návratová hodnota handleru může být null nebo false.

Hodnota false říká, že se zavolá ještě standardní PHP handler. Ten podle konfigurace PHP může chybu vypsat, zalogovat atd. Zpřístupní ji také funkci error_get_last().

Potlačené chyby

V PHP lze potlačit zobrazování chyb buď pomocí shut-up operátoru @ nebo pomocí error_reporting():

// potlač chyby úrovně E_USER_DEPRECATED
error_reporting(~E_USER_DEPRECATED);

// potlač všechny chyby při volání fopen()
$file = @fopen($name, 'r');

I při potlačení chyb dojde k volání handleru. Proto je nejprve nutné ověřit, zda chyba je potlačená, a pokud ano, tak musíme zpracování ukončit:

if (($severity & error_reporting()) !== $severity) {
	return false;
}

Zpracování musíme v tomto případě ukončit pomocí return false, aby se spustil ještě standardní error handler. Ten nic nevypíše a nezaloguje (protože je chyba potlačená), ale zajistí, že chybu půjde zjistit pomocí error_get_last().

Ostatní chyby

Pokud handler chybu zpracuje (například vypíše vlastní hlášku atd.), už není potřeba volat standardní handler. Sice pak nebude možné chybu zjistit pomocí error_get_last(), ale to v praxi nevadí, protože tato funkce se používá především v kombinaci s shut-up operátorem.

Pokud naopak handler chybu nezpracuje, měl by vrátit false, aby ji nezatajil.

Zanechat komentář

Text komentáře
Kontakt

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--

phpFashion © 2004, 2023 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.