Намиране на грешки в php скриптове

В сериозни сайтове е странно да се види, когато грешките се показват на потребителя в браузъра на най-неочаквани места. Защо се появяват? В крайна сметка текстът на грешките е информация за отстраняване на грешки и е предназначен за разработчика, а не за клиента. Ние пишем програма, която регистрира грешки и ги скрива от потребителя.

В сериозни сайтове е странно да се види, когато грешките се показват на потребителя в браузъра на най-неочаквани места. Защо се появяват е отделен разговор. Но защо се появяват? В крайна сметка текстът на грешките е информация за отстраняване на грешки и е предназначен за разработчика, а не за клиента.

В допълнение, именно тази служебна информация обикновено помага на злите хакери да пробият сайта. Като класически пример можем да цитираме опцията с изхода на заявка при грешка: "имате грешка в заявка близо до WHERE >. Благодаря ви много. Ние заместваме след "WHERE 0 OR 1> 0" и заявката се изпълнява в цялата таблица. Ако заявката е за изтриване, тогава. разбирате, забавно е =). Затова винаги затварям променливи в заявки в кавички.За всеки случай.

Но се увлякох. Днес не става въпрос за това. Днес ще говорим за това как да избегнем показването на грешки на клиента, като същевременно запазим всички съобщения на уеб администратора като спомен.

Нека започнем с кратък преглед на видовете грешки в PHP.

Таблица 1. Описания на грешки в PHP4(оригинален списък)

Числова стойност Константа Описание Catch/none
1E_ERRORфатални грешки. Например грешка при достъп до паметта. След това изпълнението на скрипта се прекъсва.Не
2E_ПРЕДУПРЕЖДЕНИЕПредупреждения (нефатални грешки). Изпълнението на скрипта не се прекъсва.да
4E_PARSEГрешки по време на анализасинтаксис. генерирани от анализатора.Не
8E_NOTICEЗабележки (по-малко сериозни грешки, отколкото предупреждения). Показва ситуация, която може да причини по-сериозна грешка, но може да възникне и по време на нормална работа на скрипта.да
16E_CORE_ERRORГрешки при зареждане на PHP. Аналог на E_ERROR, генериран от PHP ядрото.Не
32E_CORE_WARNINGПредупреждения за зареждане на PHP, подобни на E_WARNING, генерирани от PHP ядрото.Не
64E_COMPILE_ERRORФатални грешки по време на компилация на код. Аналог на E_ERROR, генериран от двигателя Zend.Не
128E_COMPILE_WARNINGПредупреждения по време на компилация на код. Аналог на E_WARNING, генериран от двигателя Zend.Не
256E_USER_ERRORПотребителска грешка.да
512E_USER_WARNINGПерсонализиран сигнал.да
1024E_USER_NOTICEБележка за потребителяда

Ние се интересуваме от тези грешки, които можем да прихванем. Те включват: E_WARNING, E_NOTICE и E_USER_*. Други типове грешки не могат да бъдат уловени, или защото се появяват дори преди самото PHP ядро ​​да е приключило зареждането, или защото се появяват на етапа на анализиране и компилиране на PHP кода, така че изходът им просто ще трябва да бъде изключен:

Но предполагам, че нашите скриптове са достатъчно дебъгвани, така че да нямат елементарни синтактични грешки, така че не трябва да губим нищо.

Процент на грешки по подразбиране в PHPе E_ALL &

E_NOTICE (или 2039 в цифрова форма), което означава, че игнорираме забележките, но докладваме всички останали грешки.

Между другото, самите разработчици препоръчват активирането на E_NOTICE на етапа на разработка - това помага да се открият потенциално опасни места.

Така че нека променим изходното ниво на грешка на E_ALL:

Сега нека предефинираме манипулатора на грешки и да го заменим с нашата функция user_log(), която сега ще се занимава с обработката на грешки:

Нека разгледаме тази функция по-подробно. Предават се 5 параметъра:

  • код на грешка
  • текст за грешка
  • името на файла, в който е възникнала грешката
  • ред във файл
  • променлив масив

Тази функция не е задължителна за връщане на нищо. Тъй като ще прегледаме регистъра на грешките по-късно, трябва да го напишем например във файл, за да ни е удобно да работим с него по-късно.

Можете да видите целия код тук или да вземете всичко в архива.

Човек, разбира се, може да използва по-логично хранилище за такива цели - базата данни, но в крайна сметка грешките в по-голямата си част възникват точно при работа с базата данни, така че не бих разчитал на нея.

Всъщност това е всичко. Останалото, мисля, няма да ви затрудни, особено ако използвате файла (); & експлодирам(); . И ако го направи, тогава можете да използвате [този код].

Предвиждайки въпроса „защо не използвах CSV, което би изглеждало логично да използвам в тази ситуация?“, отговарям: съобщенията за грешка могат да съдържат неизвестен брой служебни знаци (известни още като запетаи и точка и запетая), което очевидно би затруднило анализирането на CSV. И няма да гледам дневника в Excel.

Други мисли по тази тема:

  • пристареене дневник gz'ipovat файл и да го добавите към архива;
  • същото, но с колет по пощата;
  • ако възникнат критични грешки, изпратете имейл (вижте примера от ръководството за функцията set_error_handler);
  • за мазохистите можете да използвате XML в този случай (вижте тук);

Диша спокойно? Надявам се не. За предефинирането на манипулатора на грешки в никакъв случай не е панацея, а само една от удобните функции на PHP.

Който е предупреден е защитен - нали?

ps Признавам, малко параноичен. Но е по-добре да проверите два пъти, отколкото да направите грешка веднъж.