<rmcreative>

RSS

Сообщения об ошибках и хороший код

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

  1. №4410
    Тормоз
    Тормоз 17 апр. 2011 г., 8:09:25

    А я раньше использую error_reporting(7) в начале PHP-скрипта, но сейчас читаю и вообще ничерта не понимаю... Тут вот про уровни - http://docs.php.net/manual/ru/errorfunc.constants.php

    Что-то изменилось, похоже. Или я туплю.

  2. №4412
    Ti
    Ti 17 апр. 2011 г., 9:46:04

    валидатор формы на стороне базы данных ;)

  3. №4414
    SpiLLeR
    SpiLLeR 17 апр. 2011 г., 13:32:05

    Хорошая практика, такие настройки ставить по умолчанию. Единственное, когда приходится работать с чужим старым кодом, то иногда количество нотисов просто заваливает, поэтому приходится менять уровень ошибок.

  4. №4416
    Павел
    Павел 17 апр. 2011 г., 14:58:02

    Изначально считал этот подход верным. Но последнее время посещают противоположные мысли: а стоит ли оно того?

    Местами приходится писать глупости и просто лишний код для того, чтобы угодить компилятору. Взамен - крайне редкие ошибочки, легко отлавливаемые даже при грубом тестировании.

    От жёстких дебагов не спасает, так как их частый источник - описка с заменой одной законной переменной на другую не менее законную. Но в любом случае они тоже крайне редки.

  5. №4417
    Павел
    Павел 17 апр. 2011 г., 15:00:55

    В JS нет, например, нотисов об отсутствующих полях объектов. И это на поверку вышло удобнее, чем в PHP со включенными нотисами. Причём без сколько-нибудь ощутимой расплаты.

  6. №4433
    Константин
    Константин 18 апр. 2011 г., 15:11:30

    то, что большинство не обращает (так ли это?) внимания на орфографические ошибки не означает, что надо писать безграмотно.

    чем программирование хуже?

  7. №4434
    Ekstazi
    Ekstazi 18 апр. 2011 г., 22:04:15

    А меня всегда бесят нотайсы, особенно когда на сервер заливаешь с включеными нотайсами, заказчик смотри и говорит - что вы залили, оно же не работает, там куча ошибок )) приходитсмя писать что-то типа error_reporting(7) :)

  8. №4435
    Sam
    Sam 19 апр. 2011 г., 1:18:20

    Павел, какие, например, глупости?

    Ekstazi, они не просто так придуманы…

  9. №4438
    Павел
    Павел 19 апр. 2011 г., 11:16:05

    Сказанное верно при орг. запрете на использование @ оператора. Т.е. вопрос стоит не столько в глобальном отключении нотисов, сколько в декриминализации собаки в наперёд заданном наборе случаев. Ну и то, что она пока тормозная не последнюю роль играет.

    Самая частая ситуация при чтении ключа: isset($foo['bar']) ? $foo['bar'] : null; То есть смысла на $foo['bar'], а специфичного для компилятора мусора в два раза больше.

    В принципе, остальные редки. Зато эта встречается очень часто, при чтении из внешних источников, да и при построении структур.

    Вот ещё: if (file_exists($file)) unlink($file); вместо @unlink($file); второй вариант по смыслу ближе к тому, что хотели выразить.

  10. №4439
    Ekstazi
    Ekstazi 19 апр. 2011 г., 11:45:10

    Sam, ИМХО, от нотайсов польза есть только на этапе разработки и отладки, но порой обход этих нотайсов так может код раздуть :)

  11. №4449
    mitallast
    mitallast 19 апр. 2011 г., 23:04:55

    Поддержу Sam . Появление notice && warning - очень часто признак небрежного кода, который скорее всего плохо спроектирован. Нужно периодически слезать с php в сторону языков со строгой типизацией, развитыми ООП-инструментами, чисто функциональные языки также стоит посмотреть. Сильно прочищает мозги и код соответственно.

    Насчет javascript и notice. Откойте хоть раз фаербаг в strict режиме, или попробуйте пройти валидатор EcmaScript. Думаю, сильно удивитесь.

    По поводу собак. В php распространилась отстойная практика возвращать false или null при непредвиденной ошибке, типа попытки удалить отсутствующий файл. Языки типа Java, Python выкидывают нормальное исключение об ошибке. Изначально в php дурная обработка ошибок, и это в итоге привело к таким вот костылям, как собаки =( Возвращение false вместо exception приводит к огромному количеству if-ов, частенько вложенных в количествах неадекватных.

  12. №4454
    Тормоз
    Тормоз 20 апр. 2011 г., 7:31:13

    Ну а обработка исключений разве намного лучше ifов? Тоже не сладко вроде как. А если их не обрабатывать, скрипт всё равно вывалится.

  13. №4455
    mitallast
    mitallast 20 апр. 2011 г., 8:10:05

    В нормальных языках для конструкции try catch есть модификатор finally. В php почему-то можно throw'ить только объекты типа Exception, потому finally отсутствует - вместо него можно поставить catch Exception, который и отловит все исключения. Когда вместо ошибки возвращают false, в коде невозможно понять что случилось, какого рода ошибка возникла. Ну и что в этом хорошего? Вот и наплодилось в php всяких функций, которые при ошибке что только не возвращают. Более того, бизнес-логика сильно засоряется этими if'ами для обработки ошибок. Для того, чтобы можно было упавлять ошибками, ввели объекты, которые описывают ошибку - exceptions. В языках, где ООП не костыльно, объектом ошибки может выступать любой объект, например строка. Exception также выступает в виде отличной документации. В идеале нужно писать код, который описывает только бизнес логику, и отдельно от нее обработку исключений. Это позволяет использовать достаточно много слоев абстракции, без огромного Угличества условной логики, сосредоточенной в одном месте.

  14. №4456
    Тормоз
    Тормоз 20 апр. 2011 г., 8:42:51

    Я правильно понимаю, что этот finally из ваших слов позволяет сделать обработчик на любое исключение, и записывать их в логи, например, без падения всего скрипта для многих ситуаций?

  15. №4457
    mitallast
    mitallast 20 апр. 2011 г., 8:52:25

    finally == throw Exception в php. Смысл его - перехватить Exception, который небыл перехвачен. Что уже делать с ним - писать в лог, отсылать на почту, или выводить сообщение об ошибке - задача программиста.

  16. №4458
    mitallast
    mitallast 20 апр. 2011 г., 8:53:42

    В смысле, finally == catch Exception

  17. №4459
    andipas
    andipas 20 апр. 2011 г., 9:17:12

    mitallast Правильно ли я понимаю, что если бы функция unlink выдавала Exeption, то чтобы ей воспользоваться, пришлось бы делать так:

    try { unlink($file_path); } catch (Exception $e) { echo $e; }

    т.е. при вызове любой функции где есть Exeption, или метода в ООП надо делать так?

  18. №4460
    Тормоз
    Тормоз 20 апр. 2011 г., 9:25:09

    Спасибо за ликбез.

  19. №4461
    andipas
    andipas 20 апр. 2011 г., 9:31:04

    Вот нашел на хабре статью как раз по теме Exeption vs IF http://habrahabr.ru/blogs/php/21376/

    Давно уже пытаюсь вникнуть в "прелесть" Exeption, вроде бы теперь прояснилось. Просто делаем try не для каждой отдельной функции или метода, а для целого куска кода, и обрабатываем ошибки этого "куска" уже в конце.

  20. №4463
    mitallast
    mitallast 20 апр. 2011 г., 18:06:34

    andipas, да, именно! Вся прелесть в том, что нужен всего один блок try-catch, а не куча if-ов, разбросанных по коду.

  21. №4470
    andipas
    andipas 21 апр. 2011 г., 10:23:27

    mitallast, с одной стороны это здорово, но порой в самом методе мы обращаемся к нескольким функциям или другим методам, но что то я не вижу чтобы везде юзали try catch а при такой логике выходит их нужно вставлять везде где используется функции...

  22. №4521
    Тормоз
    Тормоз 29 апр. 2011 г., 20:39:22

    Сменил окружение для разработки, поставил в Debian PHP-FPM, а там, оказывается, в php.ini ещё display_errors Off умолчально, из-за этого никакие ошибки не показывались ("белый экран"). Может кому поможет, я не сразу додумался в чём дело.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.