Сообщения об ошибках и хороший код
17 апреля 2011
Как ни странно, очень многие разработчики пренебрегают более строгими режимами работы тех же PHP и MySQL. Странно это, прежде всего, потому, что включение таких режимов позволяет получать больше информации о потенциальных ошибках в коде и, соответственно писать код лучше.
В PHP самый строгий уровень ошибок можно получить записав в php.ini:
error_reporting = -1
Это позволяет выявить такие слабые места, как, например, использование переменных без их объявления. Да и банальные описки выявляются сразу, а не после пары часов жёсткого дебага.
В MySQL тоже есть строгий режим, который не позволяет, например, вставить строку длиной в 200 символов в поле varchar(20)
. В «умолчательном» режиме MySQL молча вставит первые 20 символов, выкинув остальные. В строгом — получим соответствующую ошибку. Включается этот режим через my.cnf
:
[mysqld] sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE"
Все значения sql-mode
можно подсмотреть в официальной документации.
Комментарии RSS по email OK
А я раньше использую error_reporting(7) в начале PHP-скрипта, но сейчас читаю и вообще ничерта не понимаю... Тут вот про уровни - http://docs.php.net/manual/ru/errorfunc.constants.php
Что-то изменилось, похоже. Или я туплю.
валидатор формы на стороне базы данных ;)
Хорошая практика, такие настройки ставить по умолчанию. Единственное, когда приходится работать с чужим старым кодом, то иногда количество нотисов просто заваливает, поэтому приходится менять уровень ошибок.
Изначально считал этот подход верным. Но последнее время посещают противоположные мысли: а стоит ли оно того?
Местами приходится писать глупости и просто лишний код для того, чтобы угодить компилятору. Взамен - крайне редкие ошибочки, легко отлавливаемые даже при грубом тестировании.
От жёстких дебагов не спасает, так как их частый источник - описка с заменой одной законной переменной на другую не менее законную. Но в любом случае они тоже крайне редки.
В JS нет, например, нотисов об отсутствующих полях объектов. И это на поверку вышло удобнее, чем в PHP со включенными нотисами. Причём без сколько-нибудь ощутимой расплаты.
то, что большинство не обращает (так ли это?) внимания на орфографические ошибки не означает, что надо писать безграмотно.
чем программирование хуже?
А меня всегда бесят нотайсы, особенно когда на сервер заливаешь с включеными нотайсами, заказчик смотри и говорит - что вы залили, оно же не работает, там куча ошибок )) приходитсмя писать что-то типа error_reporting(7) :)
Павел, какие, например, глупости?
Ekstazi, они не просто так придуманы…
Сказанное верно при орг. запрете на использование @ оператора. Т.е. вопрос стоит не столько в глобальном отключении нотисов, сколько в декриминализации собаки в наперёд заданном наборе случаев. Ну и то, что она пока тормозная не последнюю роль играет.
Самая частая ситуация при чтении ключа: isset($foo['bar']) ? $foo['bar'] : null; То есть смысла на $foo['bar'], а специфичного для компилятора мусора в два раза больше.
В принципе, остальные редки. Зато эта встречается очень часто, при чтении из внешних источников, да и при построении структур.
Вот ещё: if (file_exists($file)) unlink($file); вместо @unlink($file); второй вариант по смыслу ближе к тому, что хотели выразить.
Sam, ИМХО, от нотайсов польза есть только на этапе разработки и отладки, но порой обход этих нотайсов так может код раздуть :)
Поддержу Sam . Появление notice && warning - очень часто признак небрежного кода, который скорее всего плохо спроектирован. Нужно периодически слезать с php в сторону языков со строгой типизацией, развитыми ООП-инструментами, чисто функциональные языки также стоит посмотреть. Сильно прочищает мозги и код соответственно.
Насчет javascript и notice. Откойте хоть раз фаербаг в strict режиме, или попробуйте пройти валидатор EcmaScript. Думаю, сильно удивитесь.
По поводу собак. В php распространилась отстойная практика возвращать false или null при непредвиденной ошибке, типа попытки удалить отсутствующий файл. Языки типа Java, Python выкидывают нормальное исключение об ошибке. Изначально в php дурная обработка ошибок, и это в итоге привело к таким вот костылям, как собаки =( Возвращение false вместо exception приводит к огромному количеству if-ов, частенько вложенных в количествах неадекватных.
Ну а обработка исключений разве намного лучше ifов? Тоже не сладко вроде как. А если их не обрабатывать, скрипт всё равно вывалится.
В нормальных языках для конструкции try catch есть модификатор finally. В php почему-то можно throw'ить только объекты типа Exception, потому finally отсутствует - вместо него можно поставить catch Exception, который и отловит все исключения. Когда вместо ошибки возвращают false, в коде невозможно понять что случилось, какого рода ошибка возникла. Ну и что в этом хорошего? Вот и наплодилось в php всяких функций, которые при ошибке что только не возвращают. Более того, бизнес-логика сильно засоряется этими if'ами для обработки ошибок. Для того, чтобы можно было упавлять ошибками, ввели объекты, которые описывают ошибку - exceptions. В языках, где ООП не костыльно, объектом ошибки может выступать любой объект, например строка. Exception также выступает в виде отличной документации. В идеале нужно писать код, который описывает только бизнес логику, и отдельно от нее обработку исключений. Это позволяет использовать достаточно много слоев абстракции, без огромного Угличества условной логики, сосредоточенной в одном месте.
Я правильно понимаю, что этот finally из ваших слов позволяет сделать обработчик на любое исключение, и записывать их в логи, например, без падения всего скрипта для многих ситуаций?
finally == throw Exception в php. Смысл его - перехватить Exception, который небыл перехвачен. Что уже делать с ним - писать в лог, отсылать на почту, или выводить сообщение об ошибке - задача программиста.
В смысле, finally == catch Exception
mitallast Правильно ли я понимаю, что если бы функция unlink выдавала Exeption, то чтобы ей воспользоваться, пришлось бы делать так:
try { unlink($file_path); } catch (Exception $e) { echo $e; }
т.е. при вызове любой функции где есть Exeption, или метода в ООП надо делать так?
Спасибо за ликбез.
Вот нашел на хабре статью как раз по теме Exeption vs IF http://habrahabr.ru/blogs/php/21376/
Давно уже пытаюсь вникнуть в "прелесть" Exeption, вроде бы теперь прояснилось. Просто делаем try не для каждой отдельной функции или метода, а для целого куска кода, и обрабатываем ошибки этого "куска" уже в конце.
andipas, да, именно! Вся прелесть в том, что нужен всего один блок try-catch, а не куча if-ов, разбросанных по коду.
mitallast, с одной стороны это здорово, но порой в самом методе мы обращаемся к нескольким функциям или другим методам, но что то я не вижу чтобы везде юзали try catch а при такой логике выходит их нужно вставлять везде где используется функции...
Сменил окружение для разработки, поставил в Debian PHP-FPM, а там, оказывается, в php.ini ещё display_errors Off умолчально, из-за этого никакие ошибки не показывались ("белый экран"). Может кому поможет, я не сразу додумался в чём дело.