Намиране на грешки в php скриптове
В сериозни сайтове е странно да се види, когато грешките се показват на потребителя в браузъра на най-неочаквани места. Защо се появяват? В крайна сметка текстът на грешките е информация за отстраняване на грешки и е предназначен за разработчика, а не за клиента. Ние пишем програма, която регистрира грешки и ги скрива от потребителя.
В сериозни сайтове е странно да се види, когато грешките се показват на потребителя в браузъра на най-неочаквани места. Защо се появяват е отделен разговор. Но защо се появяват? В крайна сметка текстът на грешките е информация за отстраняване на грешки и е предназначен за разработчика, а не за клиента.
В допълнение, именно тази служебна информация обикновено помага на злите хакери да пробият сайта. Като класически пример можем да цитираме опцията с изхода на заявка при грешка: "имате грешка в заявка близо до WHERE >. Благодаря ви много. Ние заместваме след "WHERE 0 OR 1> 0" и заявката се изпълнява в цялата таблица. Ако заявката е за изтриване, тогава. разбирате, забавно е =). Затова винаги затварям променливи в заявки в кавички.За всеки случай.
Но се увлякох. Днес не става въпрос за това. Днес ще говорим за това как да избегнем показването на грешки на клиента, като същевременно запазим всички съобщения на уеб администратора като спомен.
Нека започнем с кратък преглед на видовете грешки в PHP.
Таблица 1. Описания на грешки в PHP4(оригинален списък)
1 | E_ERROR | фатални грешки. Например грешка при достъп до паметта. След това изпълнението на скрипта се прекъсва. | Не |
2 | E_ПРЕДУПРЕЖДЕНИЕ | Предупреждения (нефатални грешки). Изпълнението на скрипта не се прекъсва. | да |
4 | E_PARSE | Грешки по време на анализасинтаксис. генерирани от анализатора. | Не |
8 | E_NOTICE | Забележки (по-малко сериозни грешки, отколкото предупреждения). Показва ситуация, която може да причини по-сериозна грешка, но може да възникне и по време на нормална работа на скрипта. | да |
16 | E_CORE_ERROR | Грешки при зареждане на PHP. Аналог на E_ERROR, генериран от PHP ядрото. | Не |
32 | E_CORE_WARNING | Предупреждения за зареждане на PHP, подобни на E_WARNING, генерирани от PHP ядрото. | Не |
64 | E_COMPILE_ERROR | Фатални грешки по време на компилация на код. Аналог на E_ERROR, генериран от двигателя Zend. | Не |
128 | E_COMPILE_WARNING | Предупреждения по време на компилация на код. Аналог на E_WARNING, генериран от двигателя Zend. | Не |
256 | E_USER_ERROR | Потребителска грешка. | да |
512 | E_USER_WARNING | Персонализиран сигнал. | да |
1024 | E_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 Признавам, малко параноичен. Но е по-добре да проверите два пъти, отколкото да направите грешка веднъж.