set_error_handler

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

set_error_handler β€” УстанавливаСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок

ОписаниС

function set_error_handler(?callable $callback, int $error_levels = E_ALL): ?callable

Ѐункция устанавливаСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ Π² скриптС.

Ѐункция опрСдСляСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ошибок, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ Π²ΠΎ врСмя выполнСния ΠΊΠΎΠ΄Π°. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ Π² прилоТСниях, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ трСбуСтся ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ»ΠΈ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΈ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½ΠΎΠΉ для прилоТСния ошибкС ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ ошибкС, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ сгСнСрировали Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ trigger_error() Π² ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ условия.

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ: PHP-Π΄Π²ΠΈΠΆΠΎΠΊ пСрСдаст ошибки, Ρ‚ΠΈΠΏΡ‹ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Π»ΠΈ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ error_levels, Π² стандартный ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли callback-функция Π²Π΅Ρ€Π½Ρ‘Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ false. Π”Π²ΠΈΠΆΠΎΠΊ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок, Π΄Π°ΠΆΠ΅ Ссли ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ошибки Π½Π΅ соотвСтствуСт настройкам, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ установили Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ error_reporting(). ΠŸΡ€ΠΈ этом Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹ error_reporting остаётся доступным для чтСния, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ ситуации.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Π·Π° остановку выполнСния скрипта Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ exit(), ΠΊΠΎΠ³Π΄Π° трСбуСтся, ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ. Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ скрипта продолТится со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ инструкции послС Ρ‚ΠΎΠΉ, которая Π²Ρ‹Π·Π²Π°Π»Π° ΠΎΡˆΠΈΠ±ΠΊΡƒ, Ссли функция ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок Π²Π΅Ρ€Π½Ρ‘Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅.

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ошибки ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Ρ‚ΠΈΠΏΠΎΠ²: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING нСзависимо ΠΎΡ‚ мСста, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка, ΠΈ Π±ΠΎΜΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ошибок уровня E_STRICT, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΈ Π² Ρ„Π°ΠΉΠ»Π΅ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ set_error_handler().

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок рСгистрируСтся ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ скрипта. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ Π΄ΠΎ запуска скрипта, поэтому Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для Ρ‚Π°ΠΊΠΈΡ… ошибок.

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²

callback

ΠŸΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ значСния null ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сбрасываСтся Π² состояниС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, ΠΈΠ½Π°Ρ‡Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ становится callback-функция со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ сигнатурой:

function handler(
Β Β Β Β int $errno,
Β Β Β Β string $errstr,
Β Β Β Β string $errfile = ?,
Β Β Β Β int $errline = ?,
Β Β Β Β array $errcontext = ?
): bool
errno
Π’ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” errno пСрСдаётся Ρ†Π΅Π»ΠΎΠ΅ число, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ошибки.
errstr
Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” errstr пСрСдаётся строка с сообщСниСм ΠΎΠ± ошибкС.
errfile
Π’ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” errfile пСрСдаётся строка с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ»Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°.
errline
Π’ Ρ‡Π΅Ρ‚Π²Ρ‘Ρ€Ρ‚Π½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” errline пСрСдаётся цСлочислСнный Π½ΠΎΠΌΠ΅Ρ€ строки, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°.
errcontext
Π’ пятый ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” errcontext пСрСдаётся массив, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π°ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ символов Π² Ρ‚ΠΎΡ‡ΠΊΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°. Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ errcontext Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ массив ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ‚ΠΎΠΉ области дСйствия, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ ошибки Π½Π΅ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ Π² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ ошибок, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ управлСния ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ….
Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

Π‘ PHP 7.2.0 ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ УБВАРЕЛ, Π° Π² PHP 8.0.0 ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π£Π”ΠΠ›Π˜Π›Π˜. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ "too few arguments", Ссли Π² callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ, Π½ΠΎ Π½Π΅ установили Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

ΠŸΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ значСния false ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ пСрСдаётся стандартному ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ ошибок.

error_levels

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ устанавливаСт маску ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ ошибок, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… сработаСт callback-функция. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ управляСт срабатываниСм ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ошибок Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ini-настройка error_reporting управляСт ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ ошибок. Π‘Π΅Π· установки маски Π΄Π²ΠΈΠΆΠΎΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ошибки ΠΈ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅Ρ‚ настройку Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹ error_reporting.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния

Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с Ρ‚ΠΈΠΏΠΎΠΌ callable, Ссли Ρ‚Π°ΠΊΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ, ΠΈΠ»ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ null, Ссли Π·Π° Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ошибок ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ встроСнный ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.

Бписок измСнСний

ВСрсия ОписаниС
8.0.0 ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ errcontext ΡƒΠ΄Π°Π»ΠΈΠ»ΠΈ. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ ошибки большС Π½Π΅ пСрСдаётся Π² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ.
7.2.0 ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ errcontext устарСл. ΠŸΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ функция выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ уровня E_DEPRECATED.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок функциями set_error_handler() ΠΈ trigger_error()

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π½ΠΈΠΆΠ΅ дСмонстрируСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΏΡƒΡ‚Ρ‘ΠΌ Π²Ρ‹Π·ΠΎΠ²Π° ошибок Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² ΠΈ ΠΈΡ… ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ:

<?php

// Ѐункция ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(
error_reporting() & $errno)) {
// Π”ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Π° error_reporting Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ этот ΠΊΠΎΠ΄ ошибки,
// поэтому ΠΏΡƒΡΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ стандартный ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок PHP
return false;
}

// ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $errstr трСбуСтся экранированиС:
$errstr = htmlspecialchars($errstr);

switch (
$errno) {
case
E_USER_ERROR:
echo
"<b>ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠ°Ρ ΠžΠ¨Π˜Π‘ΠšΠ</b> [$errno] $errstr<br />\n";
echo
" Π€Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка Π² строкС $errline Ρ„Π°ΠΉΠ»Π° $errfile";
echo
", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
echo
"Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹...<br />\n";
exit(
1);

case
E_USER_WARNING:
echo
"<b>ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ ΠŸΠ Π•Π”Π£ΠŸΠ Π•Π–Π”Π•ΠΠ˜Π•</b> [$errno] $errstr<br />\n";
break;

case
E_USER_NOTICE:
echo
"<b>ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ Π£Π’Π•Π”ΠžΠœΠ›Π•ΠΠ˜Π•</b> [$errno] $errstr<br />\n";
break;

default:
echo
"НСизвСстная ошибка: [$errno] $errstr<br />\n";
break;
}

/* НС запускаСм Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок PHP */
return true;
}

// Ѐункция тСстирования ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ошибок
function scale_by_log($vect, $scale)
{
if (!
is_numeric($scale) || $scale <= 0) {
trigger_error("log(x) для x <= 0 Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½, Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅: scale = $scale", E_USER_ERROR);
}

if (!
is_array($vect)) {
trigger_error("НСкоррСктный Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π²Π΅ΠΊΡ‚ΠΎΡ€, ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ массив Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ", E_USER_WARNING);
return
null;
}

$temp = array();
foreach (
$vect as $pos => $value) {
if (!
is_numeric($value)) {
trigger_error("Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ $pos Π½Π΅ относится ΠΊ числу, присваиваСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0 (ноль)", E_USER_NOTICE);
$value = 0;
}
$temp[$pos] = log($scale) * $value;
}

return
$temp;
}

// ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌΡΡ Π½Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
$old_error_handler = set_error_handler("myErrorHandler");

// Π’Ρ‹Π·ΠΎΠ²Π΅ΠΌ ряд ошибок, ΠΈ Π²Π½Π°Ρ‡Π°Π»Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ ΡΠΌΠ΅ΡˆΠ°Π½Π½Ρ‹ΠΉ массив с нСчисловым элСмСнтом
echo "vector a\n";
$a = array(2, 3, "foo", 5.5, 43.3, 21.11);
print_r($a);

// Π’Π΅ΠΏΠ΅Ρ€ΡŒ создадим Π΅Ρ‰Ρ‘ ΠΎΠ΄ΠΈΠ½ массив
echo "----\nvector b - a notice (b = log(PI) * a)\n";
/* Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ $pos Π½Π΅ относится ΠΊ числу, присваиваСм 0 (ноль)*/
$b = scale_by_log($a, M_PI);
print_r($b);

// ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, вмСсто массива ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ строку
echo "----\nvector c - a warning\n";
/* НСкоррСктный Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π²Π΅ΠΊΡ‚ΠΎΡ€, оТидаСтся массив Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ */
$c = scale_by_log("not array", 2.3);
var_dump($c); // NULL

// ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ ошибка, Π»ΠΎΠ³Π°Ρ€ΠΈΡ„ΠΌ нуля ΠΈΠ»ΠΈ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ числа Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½
echo "----\nvector d - fatal error\n";
/* log(x) для x <= 0 Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½, ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ: scale = $scale */
$d = scale_by_log($a, -2.5);

var_dump($d); // Π”ΠΎ этого мСста Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄ΠΎΠΉΠ΄Ρ‘ΠΌ

?>

Π’Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΡ…ΠΎΠΆ Π½Π°:

vector a
Array
(
    [0] => 2
    [1] => 3
    [2] => foo
    [3] => 5.5
    [4] => 43.3
    [5] => 21.11
)
----
vector b - a notice (b = log(PI) * a)
<b>ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ Π£Π’Π•Π”ΠžΠœΠ›Π•ΠΠ˜Π•</b> [1024] Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ 2 Π½Π΅ относится ΠΊ числу, присваиваСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0 (ноль)<br />
Array
(
    [0] => 2.2894597716988
    [1] => 3.4341896575482
    [2] => 0
    [3] => 6.2960143721717
    [4] => 49.566804057279
    [5] => 24.165247890281
)
----
vector c - a warning
<b>ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ ΠŸΠ Π•Π”Π£ΠŸΠ Π•Π–Π”Π•ΠΠ˜Π•</b> [512] НСкоррСктный Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π²Π΅ΠΊΡ‚ΠΎΡ€, ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ массив Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ<br />
NULL
----
vector d - fatal error
<b>ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠ°Ρ ΠžΠ¨Π˜Π‘ΠšΠ</b> [256] log(x) для x &lt;= 0 Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½, Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅: scale = -2.5<br />
  Π€Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка Π² строкС 44 Ρ„Π°ΠΉΠ»Π° /in/IYIBO, PHP 7.4.33 (Linux)<br />
Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹...<br />

Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅

  • ErrorException
  • error_reporting() - ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚, ΠΎ ΠΊΠ°ΠΊΠΈΡ… PHP-ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… ΡΠΎΠΎΠ±Ρ‰Π°Ρ‚ΡŒ
  • restore_error_handler() - ВосстанавливаСт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ошибок
  • get_error_handler() - ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ошибок
  • trigger_error() - Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅, ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ сообщСниС ΠΎΠ± ошибкС Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ
  • ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ ошибок
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 36 notes

up
79
Philip ΒΆ
13 years ago
By this function alone you can not catch fatal errors, there is a simple work around. Below is part of my error.php file which handles errors and exceptions in the application. Before someone complains I'll add that I do not care that I am using globals, this file is part of my mini framework and without the 'config' variable the application would crash anyways.

<?php

/**
 * Error handler, passes flow over the exception logger with new ErrorException.
 */
function log_error( $num, $str, $file, $line, $context = null )
{
    log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}

/**
 * Uncaught exception handler.
 */
function log_exception( Exception $e )
{
    global $config;
    
    if ( $config["debug"] == true )
    {
        print "<div style='text-align: center;'>";
        print "<h2 style='color: rgb(190, 50, 50);'>Exception Occured:</h2>";
        print "<table style='width: 800px; display: inline-block;'>";
        print "<tr style='background-color:rgb(230,230,230);'><th style='width: 80px;'>Type</th><td>" . get_class( $e ) . "</td></tr>";
        print "<tr style='background-color:rgb(240,240,240);'><th>Message</th><td>{$e->getMessage()}</td></tr>";
        print "<tr style='background-color:rgb(230,230,230);'><th>File</th><td>{$e->getFile()}</td></tr>";
        print "<tr style='background-color:rgb(240,240,240);'><th>Line</th><td>{$e->getLine()}</td></tr>";
        print "</table></div>";
    }
    else
    {
        $message = "Type: " . get_class( $e ) . "; Message: {$e->getMessage()}; File: {$e->getFile()}; Line: {$e->getLine()};";
        file_put_contents( $config["app_dir"] . "/tmp/logs/exceptions.log", $message . PHP_EOL, FILE_APPEND );
        header( "Location: {$config["error_page"]}" );
    }
    
    exit();
}

/**
 * Checks for a fatal error, work around for set_error_handler not working on fatal errors.
 */
function check_for_fatal()
{
    $error = error_get_last();
    if ( $error["type"] == E_ERROR )
        log_error( $error["type"], $error["message"], $error["file"], $error["line"] );
}

register_shutdown_function( "check_for_fatal" );
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
ini_set( "display_errors", "off" );
error_reporting( E_ALL );
up
46
elad dot yosifon at gmail dot com ΒΆ
12 years ago
<?php
/**
 * throw exceptions based on E_* error types
 */
set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
{
    // error was suppressed with the @-operator
    if (0 === error_reporting()) { return false;}
    switch($err_severity)
    {
        case E_ERROR:               throw new ErrorException            ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_WARNING:             throw new WarningException          ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_PARSE:               throw new ParseException            ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_NOTICE:              throw new NoticeException           ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_CORE_ERROR:          throw new CoreErrorException        ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_CORE_WARNING:        throw new CoreWarningException      ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_COMPILE_ERROR:       throw new CompileErrorException     ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_COMPILE_WARNING:     throw new CoreWarningException      ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_USER_ERROR:          throw new UserErrorException        ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_USER_WARNING:        throw new UserWarningException      ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_USER_NOTICE:         throw new UserNoticeException       ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_STRICT:              throw new StrictException           ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_RECOVERABLE_ERROR:   throw new RecoverableErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_DEPRECATED:          throw new DeprecatedException       ($err_msg, 0, $err_severity, $err_file, $err_line);
        case E_USER_DEPRECATED:     throw new UserDeprecatedException   ($err_msg, 0, $err_severity, $err_file, $err_line);
    }
});

class WarningException              extends ErrorException {}
class ParseException                extends ErrorException {}
class NoticeException               extends ErrorException {}
class CoreErrorException            extends ErrorException {}
class CoreWarningException          extends ErrorException {}
class CompileErrorException         extends ErrorException {}
class CompileWarningException       extends ErrorException {}
class UserErrorException            extends ErrorException {}
class UserWarningException          extends ErrorException {}
class UserNoticeException           extends ErrorException {}
class StrictException               extends ErrorException {}
class RecoverableErrorException     extends ErrorException {}
class DeprecatedException           extends ErrorException {}
class UserDeprecatedException       extends ErrorException {}
up
11
dannykopping at gmail dot com ΒΆ
12 years ago
Keep in mind that, when attempting to set a statically-defined error handler on a namespaced class in PHP >= 5.3, you need to use the class namespace:

<?php
set_error_handler('\\My\\Namespace\\Bob::errorHandler');
?>
up
17
aditycse at gmail dot com ΒΆ
10 years ago
<?php
/**
 * Used for logging all php notices,warings and etc in a file when error reporting
 * is set and display_errors is off
 * @uses used in prod env for logging all type of error of php code in a file for further debugging
 * and code performance
 * @author Aditya Mehrotra<aditycse@gmail.com>
 */
error_reporting(E_ALL);
ini_set("display_errors", "off");
define('ERROR_LOG_FILE', '/var/www/error.log');

/**
 * Custom error handler
 * @param integer $code
 * @param string $description
 * @param string $file
 * @param interger $line
 * @param mixed $context
 * @return boolean
 */
function handleError($code, $description, $file = null, $line = null, $context = null) {
    $displayErrors = ini_get("display_errors");
    $displayErrors = strtolower($displayErrors);
    if (error_reporting() === 0 || $displayErrors === "on") {
        return false;
    }
    list($error, $log) = mapErrorCode($code);
    $data = array(
        'level' => $log,
        'code' => $code,
        'error' => $error,
        'description' => $description,
        'file' => $file,
        'line' => $line,
        'context' => $context,
        'path' => $file,
        'message' => $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']'
    );
    return fileLog($data);
}

/**
 * This method is used to write data in file
 * @param mixed $logData
 * @param string $fileName
 * @return boolean
 */
function fileLog($logData, $fileName = ERROR_LOG_FILE) {
    $fh = fopen($fileName, 'a+');
    if (is_array($logData)) {
        $logData = print_r($logData, 1);
    }
    $status = fwrite($fh, $logData);
    fclose($fh);
    return ($status) ? true : false;
}

/**
 * Map an error code into an Error word, and log location.
 *
 * @param int $code Error code to map
 * @return array Array of error word, and log location.
 */
function mapErrorCode($code) {
    $error = $log = null;
    switch ($code) {
        case E_PARSE:
        case E_ERROR:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
        case E_USER_ERROR:
            $error = 'Fatal Error';
            $log = LOG_ERR;
            break;
        case E_WARNING:
        case E_USER_WARNING:
        case E_COMPILE_WARNING:
        case E_RECOVERABLE_ERROR:
            $error = 'Warning';
            $log = LOG_WARNING;
            break;
        case E_NOTICE:
        case E_USER_NOTICE:
            $error = 'Notice';
            $log = LOG_NOTICE;
            break;
        case E_STRICT:
            $error = 'Strict';
            $log = LOG_NOTICE;
            break;
        case E_DEPRECATED:
        case E_USER_DEPRECATED:
            $error = 'Deprecated';
            $log = LOG_NOTICE;
            break;
        default :
            break;
    }
    return array($error, $log);
}

//calling custom error handler
set_error_handler("handleError");

print_r($arra); //undefined variable
print_r($dssdfdfgg); //undefined variable
include_once 'file.php'; //No such file or directory
?>
up
5
steve962 at gmail dot com ΒΆ
8 years ago
Be careful when using the return value to this function.   Because it returns the old handler, you may be tempted to do something like:

<?php
function do_something()
    {
    $old = set_error_handler(β€œmy_error_handler”);
    // Do something you want handled by my_error_handler
    set_error_handler($old);
    }
?>

This will work, but it will bite you because each time you do this, it will cause a memory leak as the old error handler is put on a stack for the restore_error_handler() function to use.

So always restore the old error handler using that function instead:

<?php
function do_something()
    {
    set_error_handler(β€œmy_error_handler”);
    // Do something you want handled by my_error_handler
    restore_error_handler();
    }
?>
up
9
kalle at meizo dot com ΒΆ
16 years ago
This may be of help to someone, who is/was looking for a way to get a backtrace of fatal errors such as maximum memory allocation issues, which can not be handled with user-defined functions, to pin-point the problem:

On a server hosting many sites that share common PHP includes, I set in one spot:

<?php
@ini_set ("error_log", "/my/path/php.err-" . $_SERVER ["HTTP_HOST"] . "-" . $_SERVER ["REMOTE_ADDR"] . "-" . $_SERVER ["REQUEST_METHOD"] . "-" . str_replace ("/", "|", $_SERVER ["REQUEST_URI"]));
?>

I actually used some additional information too from my software that I omitted, but that way, you'll find errors sorted more neatly in for example:-

/my/path/php.err-website.com-127.0.0.1-GET-path|index.html?xyz 

And that at least helped me tremendously to then further pin-point where the problem is, as opposed to before just seeing the out of memory and not knowing which site/page it was on (as the PHP error only contains the very latest PHP code where it ran out of memory, which usually is just a shared included file, not the actual page).
up
6
Jacob Slomp ΒΆ
13 years ago
This might be handy if you don't want your clients to see the errors, and you do want to be one step ahead of them.

It emails you the errors even if it's a parse error.

set_error_handler() doesn't work for what I wanted.

<?php
ini_set('log_errors',TRUE);
ini_set('error_log','tiny_uploads/errors.txt');

if($_SERVER['REMOTE_ADDR'] != "YOUR IP ADDRESS"){
    ini_set('display_errors',false);
}
   
function byebye(){

        $dir = dirname(__FILE__);
        if(file_exists($dir."/tiny_uploads/errors.txt")){
        
            $errors = file_get_contents($dir."/tiny_uploads/errors.txt");
            
            if(trim($errors)){
            
                $head = "From: php_errors@".str_replace('www.','',$_SERVER['HTTP_HOST'])."\r\n";
                
                $errors .= "---------------------------------------------\n\n";
                
                $errors .= "\n\nServer Info:\n\n".print_r($_SERVER, 1)."\n\n";
                $errors .= "---------------------------------------------\n\n";
                
                $errors .= "\n\nCOOKIE:\n\n".print_r($_COOKIE, 1)."\n\n";
                $errors .= "---------------------------------------------\n\n";
                
                $errors .= "\n\nPOST:\n\n".print_r($_POST, 1)."\n\n";
                $errors .= "---------------------------------------------\n\n";
                
                $errors .= "\n\nGET:\n\n".print_r($_GET, 1)."\n\n";
                
                
                mail("YOUR@EMAIL.COM","PHP Error ".$_SERVER['HTTP_HOST']."", $errors , $head);
                
                $fp = fopen($dir."/tiny_uploads/errors.txt","w+");
                fputs($fp, "");
                fclose($fp);    
            }    
        }
}
register_shutdown_function("byebye");
?>
up
1
David Spector ΒΆ
5 years ago
The PHP manual is not very clear about how to handle @ operator error messages.

Here is working code:

    // Do nothing if @ operator
    $errLevel=error_reporting(E_ALL);
    if ($errLevel===0)
        return true; // ignore @ prefixed expression errors
up
1
a dot ross at amdev dot eu ΒΆ
7 years ago
I'm missing a way to chain error handlers. It's not something offered by set_error_handler. You have to jump through some hoops to get it to work, but it *is* quite possible, by making use of the return value of the function. Here's an example:

<?
$previous = set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) use (&$previous) {
    /* Your custom error handling code here. */

    // If another error handler was defined, call it.
    if ($previous) {
        return $previous($errno, $errstr, $errfile, $errline, $errcontext);
    } else {
        // Use the standard PHP error handler.
        return false;
    }
});
?>
up
5
wfinn at riverbed dot com ΒΆ
17 years ago
"The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called."

This is not exactly true.  set_error_handler() can't handle them, but ob_start() can handle at least E_ERROR.

<?php

function error_handler($output)
{
    $error = error_get_last();
    $output = "";
    foreach ($error as $info => $string)
        $output .= "{$info}: {$string}\n";
    return $output;
}

ob_start('error_handler');

will_this_undefined_function_raise_an_error();

?>
up
5
dorphalsig at NOSPAMgmail dot com ΒΆ
14 years ago
This actually works to catch Fatal errors...

<?php
function shutdown()
{
    $a=error_get_last();
    if($a==null)   
        echo "No errors";
    else
         print_r($a);
    
}
register_shutdown_function('shutdown');
ini_set('max_execution_time',1 );
sleep(3);
?>

it will output
Array ( [type] => 1 [message] => Maximum execution time of 1 second exceeded [file] => /path/to/file_name.php [line] => 136 )
up
5
silkensedai at online dot fr ΒΆ
19 years ago
i made an error handler that print also the backtrace and that can die on some errors. It can be useful if you want to die on every error you find.

<?php

function my_error_handler($errno, $errstr, $errfile, $errline){
    $errno = $errno & error_reporting();
    if($errno == 0) return;
    if(!defined('E_STRICT'))            define('E_STRICT', 2048);
    if(!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR', 4096);
    print "<pre>\n<b>";
    switch($errno){
        case E_ERROR:               print "Error";                  break;
        case E_WARNING:             print "Warning";                break;
        case E_PARSE:               print "Parse Error";            break;
        case E_NOTICE:              print "Notice";                 break;
        case E_CORE_ERROR:          print "Core Error";             break;
        case E_CORE_WARNING:        print "Core Warning";           break;
        case E_COMPILE_ERROR:       print "Compile Error";          break;
        case E_COMPILE_WARNING:     print "Compile Warning";        break;
        case E_USER_ERROR:          print "User Error";             break;
        case E_USER_WARNING:        print "User Warning";           break;
        case E_USER_NOTICE:         print "User Notice";            break;
        case E_STRICT:              print "Strict Notice";          break;
        case E_RECOVERABLE_ERROR:   print "Recoverable Error";      break;
        default:                    print "Unknown error ($errno)"; break;
    }
    print ":</b> <i>$errstr</i> in <b>$errfile</b> on line <b>$errline</b>\n";
    if(function_exists('debug_backtrace')){
        //print "backtrace:\n";
        $backtrace = debug_backtrace();
        array_shift($backtrace);
        foreach($backtrace as $i=>$l){
            print "[$i] in function <b>{$l['class']}{$l['type']}{$l['function']}</b>";
            if($l['file']) print " in <b>{$l['file']}</b>";
            if($l['line']) print " on line <b>{$l['line']}</b>";
            print "\n";
        }
    }
    print "\n</pre>";
    if(isset($GLOBALS['error_fatal'])){
        if($GLOBALS['error_fatal'] & $errno) die('fatal');
    }
}

function error_fatal($mask = NULL){
    if(!is_null($mask)){
        $GLOBALS['error_fatal'] = $mask;
    }elseif(!isset($GLOBALS['die_on'])){
        $GLOBALS['error_fatal'] = 0;
    }
    return $GLOBALS['error_fatal'];
}

?>

Usage :

<?php
error_reporting(E_ALL);      // will report all errors
set_error_handler('my_error_handler');
error_fatal(E_ALL^E_NOTICE); // will die on any error except E_NOTICE
?>
up
2
phil at propcom dot co dot uk ΒΆ
12 years ago
It is important to note that the registered SPL autoloader will NOT be called if an E_STRICT error triggers the error handler which, in turn, tries to use classes which are not yet loaded. 

In this instance, you should manually load classes required by the error handler.
up
2
webmaster at paramiliar dot com ΒΆ
18 years ago
We needed to use an error handler to handle SQL errors while passing the query along so the query is also logged and this is what we came up with, its kind of an ugly bridge but it works 100%

<?php

function myErrorHandler($errno, $errstr, $errfile, $errline){
    switch ($errno) {
    case E_USER_ERROR:
        if ($errstr == "(SQL)"){
            // handling an sql error
            echo "<b>SQL Error</b> [$errno] " . SQLMESSAGE . "<br />\n";
            echo "Query : " . SQLQUERY . "<br />\n";
            echo "On line " . SQLERRORLINE . " in file " . SQLERRORFILE . " ";
            echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
            echo "Aborting...<br />\n";
        } else {
            echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
            echo "  Fatal error on line $errline in file $errfile";
            echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
            echo "Aborting...<br />\n";
        }
        exit(1);
        break;

    case E_USER_WARNING:
    case E_USER_NOTICE:
    }
    /* Don't execute PHP internal error handler */
    return true;
}

// function to test the error handling

function sqlerrorhandler($ERROR, $QUERY, $PHPFILE, $LINE){
    define("SQLQUERY", $QUERY);
    define("SQLMESSAGE", $ERROR);
    define("SQLERRORLINE", $LINE);
    define("SQLERRORFILE", $PHPFILE);
    trigger_error("(SQL)", E_USER_ERROR);
}

set_error_handler("myErrorHandler");

// trigger an sql error
$query = "SELECT * FROM tbl LIMIT 1";
$sql = @mysql_query($query)
    or sqlerrorhandler("(".mysql_errno().") ".mysql_error(), $query, $_SERVER['PHP_SELF'], __LINE__);
    

?>
up
3
nizamgok at gmail dot com ΒΆ
16 years ago
I have realized that a few people here mentioned that you cannot capture parse errors (type 4, E_PARSE). This is not true. Here is how I do. I hope this helps someone.

1) Create a "auto_prepend.php" file in the web root and add this:

<?php
register_shutdown_function('error_alert');

function error_alert()
{
        if(is_null($e = error_get_last()) === false)
        {
                mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true));
        }
}
?>

2) Then add this "php_value auto_prepend_file /www/auto_prepend.php" to your .htaccess file in the web root.

* make sure you change the email address and the path to the file.
up
6
phpmanual at NO_SPHAMnetebb dot com ΒΆ
22 years ago
Given this code:

class CallbackClass {
    function CallbackFunction() {
        // refers to $this
    }

    function StaticFunction() {
        // doesn't refer to $this
    }
}

function NonClassFunction() {
}

there appear to be 3 ways to set a callback function in PHP (using set_error_handler() as an example):

1: set_error_handler('NonClassFunction');

2: set_error_handler(array('CallbackClass', 'StaticFunction'));

3: $o =& new CallbackClass();
   set_error_handler(array($o, 'CallbackFunction'));

The following may also prove useful:

class CallbackClass {
    function CallbackClass() {
        set_error_handler(array(&$this, 'CallbackFunction')); // the & is important
    }
    
    function CallbackFunction() {
        // refers to $this
    }
}

The documentation is not clear in outlining these three examples.
up
1
Klauss ΒΆ
8 years ago
Hi everyone. I don't know if it is an old behavior of previous versions, but currently you can set exception and error handlers as private or protected methos, if, only if, you call `set_exception_handler()` or `set_error_handler()` within a context that can access the method.

Example:
    <?PHP
        $Handler = new class ()
        {
            public function __construct ()
            {
                set_error_handler([&$this, 'HandleError']);
                set_exception_handler([&$this, 'HandleException']);
            }
            protected function HandleError ( $Code, $Message, $File = null, $Line = 0, $Context = [] )
            {
                // Handle error here.
            }
            private function HandleException ( $Exception )
            {
                // Handle exception here.
            }
        }
    ?>

NOTE: these methods must match the callbacks parameters signatures.
up
2
nicolas dot grekas+php at gmail dot com ΒΆ
12 years ago
If you want to be sure that the native PHP error handler is called without resetting the handler stack (as set_error_handler(null) does), you can simply call set_error_handler with $error_types set to zero. This can be especially use full in conjunction with e.g. error_get_last():

<?php

// var_dump or anything else, as this will never be called because of the 0
set_error_handler('var_dump', 0);
@$undef_var;
restore_error_handler();

// error_get_last() is now in a well known state:
// Undefined variable: undef_var

... // Do something

$e = error_get_last();

...

?>
up
2
roy ΒΆ
23 years ago
Useful thing to note - if your error handler throws an error in itself, PHP is smart enough to use the deault error handler to handle it. This way, you don't end up in infinite flaming loops of death. This seems to be true, at least, in PHP 4.2. 

('Course, there are ways to create your handler to handle even this situation, but it's probably best left this way for general purposes.)
up
1
francois vespa ΒΆ
15 years ago
This is a note when using php from the terminal (the CLI interface). From the command line, even if you have some kind of error user handler function so STDERR will not display, fatal errors will still cause the PHP interpreter to display error text. There is nothing you can do about that php-wise. If using UNIX/Linux, you can add " 2>/dev/null" at the end of your command to force STDERR not to show
up
1
Marcelius ΒΆ
17 years ago
Another way to catch PHP's fatal errors:

<?php
    error_reporting(E_ALL);
    ini_set('display_errors', 0);

    function shutdown(){
        $isError = false;
        if ($error = error_get_last()){
            switch($error['type']){
                case E_ERROR:
                case E_CORE_ERROR:
                case E_COMPILE_ERROR:
                case E_USER_ERROR:
                    $isError = true;
                    break;
            }
        }

        if ($isError){
            echo "Script execution halted ({$error['message']})";
        } else {
            echo "Script completed";
        }
    }

    register_shutdown_function('shutdown');
?>

Note that this will only catch runtime errors. So calling a method in a non existing class, or declaring a function twice does not trigger the shutdown handler.
up
1
Anonymous ΒΆ
20 years ago
To honor the value of PHP's error_reporting() function, use:

<?
  if( ($level & error_reporting()) == 0 ) return;
?>
up
1
Anonymous ΒΆ
22 years ago
It seems that when you're letting PHP know that you have a custom  error handler, you're not able to -update/set new- variables inside the class. Example:

<?php
class error {
   var $error;

   function error() {
       $this->setIni();    // this causes PHP to ignore all other changes to the class.
   }

   function handler() {
       echo $this->error.'!!';
   }

   function setText($text) {
         $this->error = $text;
   }

   function setIni() {
       set_error_handler(array($this, 'handler'));
   }
}

$eh = new error;
$eh->setText('Error! <br>');  // this will not be saved

trigger_error('text', E_USER_ERROR);
// prints '!!'
?>

How it should be done:
<?php
class error {
   var $error;

   function error() {
         // dont let PHP know of our error handler yet
   }

   function handler() {
       echo $this->error.'!!';
   }

   function setText($text) {
         $this->error = $text;
   }

   function setIni() {
       set_error_handler(array($this, 'handler'));
   }
}

$eh = new error;
$eh->setText('Error! <br>');  // this WILL work
$eh->setIni();  // call this method when you're ready with configuring the class. All other methods that will be called will have no effect on the errorHandling by PHP

trigger_error('text', E_USER_ERROR);
// prints 'Error! <br>!!'
?>
up
1
jtrick77 at gmail dot com ΒΆ
12 years ago
For anyone interested in the actual translated error codes and their meanings:

1    E_ERROR (integer)     Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.     
2    E_WARNING (integer)     Run-time warnings (non-fatal errors). Execution of the script is not halted.     
4    E_PARSE (integer)     Compile-time parse errors. Parse errors should only be generated by the parser.     
8    E_NOTICE (integer)     Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.     
16    E_CORE_ERROR (integer)     Fatal errors that occur during PHP's initial startup. This is like an E_ERROR, except it is generated by the core of PHP.     
32    E_CORE_WARNING (integer)     Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING, except it is generated by the core of PHP.     
64    E_COMPILE_ERROR (integer)     Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine.     
128    E_COMPILE_WARNING (integer)     Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine.     
256    E_USER_ERROR (integer)     User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function trigger_error().     
512    E_USER_WARNING (integer)     User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP function trigger_error().     
1024    E_USER_NOTICE (integer)     User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error().     
2048    E_STRICT (integer)     Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code.    Since PHP 5 but not included in E_ALL until PHP 5.4.0
4096    E_RECOVERABLE_ERROR (integer)     Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR.    Since PHP 5.2.0
8192    E_DEPRECATED (integer)     Run-time notices. Enable this to receive warnings about code that will not work in future versions.    Since PHP 5.3.0
16384    E_USER_DEPRECATED (integer)     User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error().    Since PHP 5.3.0
32767    E_ALL (integer)     All errors and warnings, as supported, except of level E_STRICT prior to PHP 5.4.0.     32767 in PHP 5.4.x, 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously

(Copied from http://php.net/manual/en/errorfunc.constants.php)
up
0
gernovich at ya dot ru ΒΆ
1 year ago
Show all error handlers:
<?php
do {
  $handler = set_error_handler(fn()=>false);
  if($handler !== null) {
    var_dump($handler);
    restore_error_handler();
    restore_error_handler();
  }
} while ($handler !== null);
?>
up
0
kaioker ΒΆ
4 years ago
super simple error code to human readable conversion:

function prettycode($code){
    return $code == 0 ? "FATAL" : array_search($code, get_defined_constants(true)['Core']);
}
up
-1
regslask at protonmail dot com ΒΆ
1 year ago
Usually, this method is not called in a loop, but if it is, there is one thing that may be EXTREMELY important to think of, and that is to run `restore_error_handler()` once for each call to `set_error_handler`. Otherwise, you will have a memory leak. Every time set an error handler, even if it's identical to the previous one, you're pushing the previous one to a stack. 

We recently had a big crash due to this, and we had a very hard time finding out what the problem was. There was no error message or anything. Just a big crash.
up
-1
RGraph ΒΆ
3 years ago
A simple error handler that makes errors far more visible:

    //
    // Set the error handler to one that prints out more
    // visible errors
    //
    set_error_handler(function ($errno, $errstr)
    {
        $str = '<div style="margin: 20px; background-color: #fdd; border: 3px solid red; padding: 10px; border-radius: 15px; line-height: 25px"><b>Error: </b>%s (error level: %s)</div>';
        
        printf($str, $errstr, $errno);
    });
up
-1
Alex M ΒΆ
5 years ago
If you are new to programming and you would like to know how to add a combination of those error reporting values to .htaccess file. Here's a small guide.

With PHP function error_reporting we can add together option with bitwise add operator | . But we can't use those constants in htaccess file and in my case I have no idea how to add bitwise number.

So, solution can be casting selected options to int:

echo (int)(E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR) ;
->263

Then you can use 263 in .htaccess

php_value error_reporting 263

In my case I needed those errors to be displayed for my debugging server. But the combination can be different from mine.
up
0
chris at ocproducts dot com ΒΆ
9 years ago
Note that error handlers don't run recursively. If you have an error while an error handler is running (in the error handler itself or code called from it) then you won't get the error handler called again.

This has subtle ramifications for $php_errormsg. If you are relying on your error handler to suppress certain kinds of error message from going into $php_errormsg (via return true; because error_reporting doesn't affect $php_errormsg setting) then this will not work for any code called within that error handler.
up
0
periklis ΒΆ
15 years ago
How to handle fatal errors in php 5.2:

<?php
register_shutdown_function('shutdownFunction');
function shutDownFunction() { 
    $error = error_get_last();
    if ($error['type'] == 1) {
        //do your stuff     
    } 
}
?>
up
0
stepheneliotdewey at GmailDotCom ΒΆ
18 years ago
The manual states:

"errcontext will contain an array of every variable that existed in the scope the error was triggered in. User error handler must not modify error context."

But do you know WHY you must not modify the error context? It appears that errcontext is (in effect if not literally) created by taking $GLOBALS and adding the non-global local variables as additional entries in that array, then passing the whole thing *by reference*.

(You can prove this to be true if you set up a custom error handler and then print_r($errcontext) within it, because $GLOBALS will be printed as a recursive array).

In other words, the language in the manual is misleading, because errcontext is NOT a copy of the variables that existed when the error WAS triggered, but rather is a reference to the *existing LIVE variables* in the calling script.

This includes superglobal variables like $_SERVER, $_POST, $_GET, etc., as well as all user-defined variables in scope.

The significance of that is that if you modify errcontext, you will be modifying those other variables, not just for the life of your error handling function, but for the life of the calling script as well.

That doesn't matter if you plan to halt execution in your error handling function, but it will lead to unexpected behavior if you modify $errcontext and then return to the program's normal flow after handling the error, because the variables will stay modified. For example, if you unset $_SERVER in your custom error handling function, it will remain unset once the function is over and you have returned to the page that generated the error.

This should be made clearer in the manual, starting by marking errhandler with an ampersand (&) for passage by reference in the "Parameters" section above, like so:

handler ( int $errno, string $errstr [, string $errfile [, int $errline [, array &$errcontext]]] )
up
0
Steffen Staehle ΒΆ
21 years ago
Two notes on using set_error_handler() on behaviour that I noticed when migrating an application from php 4.2.1 to php 4.3.9 (I do not yet have php 5.0 available, this might not apply there!).

1. setting the system error handler

If you want to set the standard php error handler again, after having set your own error handler, this works in php 4.2.1 by passing in an empty string:

<?php

   function my_handler($log_level, $log_text, $error_file, $error_line)
   {
      // if an error occurs here, the standard error
      // would be called (to avoid recursion)

      // do something useful
      // ...
   }

   $last_handler = set_error_handler("my_handler");

   // after this, $last_handler == ""

   // restore standard error handler

   $last_handler = set_error_handler("");

   // after this, $last_handler == "my_handler"

?>

The very same code now raises an error in php 4.3.9:

   set_error_handler() expects argument 1, '', to be a valid callback

(Since the return value of the first call to set_error_handler() is still the empty string "", I don't see how this can be done any more. I don't really need this, because I use my own handlers as shown below, but it might be good to be aware of this.)

2. setting your own 'second level' handler

If you have set your own error handler, and want to replace it by another one (other than the standard php error handler) while it is being executed, note that the return value of set_error_handler when used INSIDE the error handler is "" instead of the name of the previous handler! This is not too surprising, because during execution of your self defined error handler, php replaces it with the standard php error handler to avoid infinite loops in case of problems inside the handler. This is only interesting if you want nested handlers as I do. Background of my design:

   1st level handler: log into DB
   2nd level handler: log into flat file (if log into DB fails)
   3rd level handler: print to stdout (if log into flat file fails) (this is the sytem handler, finally).

<?php

   function my_fallback_handler($log_level, $log_text, $error_file, $error_line)
   {
      // if an error occurs here, the standard error
      // would be called (to avoid recursion)

      // do something useful
      // ...

   } // my_fallback_handler

   function my_handler($log_level, $log_text, $error_file, $error_line)
   {
      // if an error occurs here, the standard error
      // would be called (to avoid recursion)

      // but we want to have a fallback handler different
      // to the standard error handler

      $last_handler = set_error_handler("my_fallback_handler");

      // I expected $last_handler == "my_handler" 
      // (which it would outside my_handler())
      // but here it is the empty string ""

      // do something useful
      // ...

      // now set the 1st level handler again:
      // (do NOT use $last_handler as argument,
      // because it equals "")

      $last_handler = set_error_handler("my_handler");

   } // my_handler

   $last_handler = set_error_handler("my_handler");

?>
up
-3
ash ΒΆ
18 years ago
error handling function that handles both errors and exceptions; also features a backtrace including possible function arguments.

<?php

$cfg = array();
$cfg['debug'] = 1;
$cfg['adminEmail'] = 'name@domain.tld';

function errorHandler($errno, $errstr='', $errfile='', $errline='')
{
    // if error has been supressed with an @
    if (error_reporting() == 0) {
        return;
    }

    global $cfg;

    // check if function has been called by an exception
    if(func_num_args() == 5) {
        // called by trigger_error()
        $exception = null;
        list($errno, $errstr, $errfile, $errline) = func_get_args();

        $backtrace = array_reverse(debug_backtrace());

    }else {
        // caught exception
        $exc = func_get_arg(0);
        $errno = $exc->getCode();
        $errstr = $exc->getMessage();
        $errfile = $exc->getFile();
        $errline = $exc->getLine();

        $backtrace = $exc->getTrace();
    }

    $errorType = array (
               E_ERROR            => 'ERROR',
               E_WARNING        => 'WARNING',
               E_PARSE          => 'PARSING ERROR',
               E_NOTICE         => 'NOTICE',
               E_CORE_ERROR     => 'CORE ERROR',
               E_CORE_WARNING   => 'CORE WARNING',
               E_COMPILE_ERROR  => 'COMPILE ERROR',
               E_COMPILE_WARNING => 'COMPILE WARNING',
               E_USER_ERROR     => 'USER ERROR',
               E_USER_WARNING   => 'USER WARNING',
               E_USER_NOTICE    => 'USER NOTICE',
               E_STRICT         => 'STRICT NOTICE',
               E_RECOVERABLE_ERROR  => 'RECOVERABLE ERROR'
               );

    // create error message
    if (array_key_exists($errno, $errorType)) {
        $err = $errorType[$errno];
    } else {
        $err = 'CAUGHT EXCEPTION';
    }

    $errMsg = "$err: $errstr in $errfile on line $errline";

    // start backtrace
    foreach ($backtrace as $v) {

        if (isset($v['class'])) {

            $trace = 'in class '.$v['class'].'::'.$v['function'].'(';

            if (isset($v['args'])) {
                $separator = '';

                foreach($v['args'] as $arg ) {
                    $trace .= "$separator".getArgument($arg);
                    $separator = ', ';
                }
            }
            $trace .= ')';
        }

        elseif (isset($v['function']) && empty($trace)) {
            $trace = 'in function '.$v['function'].'(';
            if (!empty($v['args'])) {

                $separator = '';

                foreach($v['args'] as $arg ) {
                    $trace .= "$separator".getArgument($arg);
                    $separator = ', ';
                }
            }
            $trace .= ')';
        }
    }

    // display error msg, if debug is enabled
    if($cfg['debug'] == 1) {
        echo '<h2>Debug Msg</h2>'.nl2br($errMsg).'<br />
            Trace: '.nl2br($trace).'<br />';
    }

    // what to do
    switch ($errno) {
        case E_NOTICE:
        case E_USER_NOTICE:
            return;
            break;

        default:
            if($cfg['debug'] == 0){
                // send email to admin
                if(!empty($cfg['adminEmail'])) {
                    @mail($cfg['adminEmail'],'critical error on '.$_SERVER['HTTP_HOST'], $errorText,
                            'From: Error Handler');
                }
                // end and display error msg
                exit(displayClientMessage());
            }
            else
                exit('<p>aborting.</p>');
            break;

    }

} // end of errorHandler()

function displayClientMessage()
{
    echo 'some html page with error message';

}

function getArgument($arg)
{
    switch (strtolower(gettype($arg))) {

        case 'string':
            return( '"'.str_replace( array("\n"), array(''), $arg ).'"' );

        case 'boolean':
            return (bool)$arg;

        case 'object':
            return 'object('.get_class($arg).')';

        case 'array':
            $ret = 'array(';
            $separtor = '';

            foreach ($arg as $k => $v) {
                $ret .= $separtor.getArgument($k).' => '.getArgument($v);
                $separtor = ', ';
            }
            $ret .= ')';

            return $ret;

        case 'resource':
            return 'resource('.get_resource_type($arg).')';

        default:
            return var_export($arg, true);
    }
}

?>
up
-2
devermin at ti0n dot net ΒΆ
16 years ago
At work I have some code with errors that uncatched are the causes of integrity loss (people calling web services with file_get_contents that fails silently and afterwards insert garbage in the database). 

here is the solution I found to transform a specific set of errors into exception and afterwards be able to selectively act (with the error code) regarding categories :  

<?php
ini_set('error_reporting',E_ALL^E_NOTICE);

## first 10 bits reserved for the initial error number
define('EMASK',(~0)<<10);
define('ECODEMASK',~EMASK);
## categories 
define('IOERROR', 1<<10);
define('EMPTYPARMS', 1<<11);
define('FAILURE', 1<<12);
## string error patterns => code 

$catch_me=array(
    "/^(file_get_contents)\((.*)\).*failed to open stream: (.*)/ " => 
        array ( 'mesg' => "IO::Failed to open stream with",
                'code' => IOERROR | FAILURE
        ),
    "/^fopen\(.*\): Filename cannot be empty/" => 
        array( 'msg' => "Parameters::empty",
                'code' => EMPTYPARMS
        )
    );
function error_2_exception($errno, $errstr, $errfile, $errline,$context) {
    global $catch_me;
    foreach ($catch_me as $regexp  => $res) {
        if(preg_match($regexp,$errstr,$match)){
            throw new Exception($res['mesg'],$res['code']|( $errno & EMASK ) );
        }
    }
    /* switch back to PHP internal error handler  */
    return false;
}
## => want to catch this one
$f=file_get_contents("mlsdkfm");
## dont want to break existing wrong behaviour yet (so not caught)
$f=file_get_contents('');
## magic
set_error_handler("error_2_exception");
## behaviour remains the same
$f=file_get_contents('');
try { 
## web services that dont work now raise an exception \o/
$f=file_get_contents("mlsdkfm");
} catch(Exception $e) {
## and I can group my exception by category
    echo ( $e->getCode() & FAILURE )  ? "\nEPIC FAIL\n" : "\nbegnine";
}

?>
up
-3
mmtache at yahoo dot com ΒΆ
23 years ago
The @ operator sets the error_reporting() value to 0.
This means you can use it with your own Error Handler too. for example:

function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
   if (error_reporting())
echo $errmsg;
    }
set_error_handler("userErrorHandler");

function test(){
trigger_error("Error Message", E_USER_WARNING);
}

@test(); // doesn't output anything