Подавление уведомлений PHP; только определенные обстоятельства / методы - PullRequest
4 голосов
/ 15 августа 2011

tl; dr - Существует ли эффективный способ управления уровнем отчетов об ошибках в PHP при работе в очень строгой среде, если бы некоторые процессы были упрощены при менее строгом уровне?

Хорошо; Во-первых, я не верю, что «подавление ошибок» - это решение. Я ( достаточно уверен, что я ) никогда не использовал оператор подавления ошибок @ и не собираюсь этого делать. Я пользуюсь set_error_handler() и ErrorException ( или некоторым производным от ) и развиваюсь в error_reporting(-1) ( в будущем E_ALL | E_STRICT)

Теперь я не хочу менять эти привычки, так как считаю, что они являются отличной практикой (); если у кого-то есть предложения по дальнейшему улучшению настроек / практик моей среды разработки / производственной среды, у меня все на слух * * тысяча двадцать-одина)

Однако, когда дело доходит до генерации просмотра, это может стать немного утомительным. Правильные данные ( индексы массива, переменные и т. Д. ) не всегда доступны, поскольку контроллер по какой-либо причине не может передать определенные данные в представление. Пока эти данные не являются критичными для генерации представления, представление все равно должно отображаться.

Мне скорее нравится этот синтаксис, поскольку он не многословен, но ( я думаю ) очень понятен:

// e() is a shortcut function; given the passed value evaluates to a boolean true
// it will echo() and return true, otherwise it simply returns false
<p><?php e($data['field']) or e('No data found'); ?></p>

Конечно, если $data['field'] не вызывает offsetGet() с null, возвращаемым в отсутствие индекса, у нас есть проблема. Уведомление встретить исключение, исключение сценария встретить сбой.

Я экспериментировал с различными реализациями, включая создание дерева данных с использованием класса, подобного узлу, для управления списками / строками данных, передаваемых в представление. __get() фактически создаст узлов ( при назначении или доступе ), которые не существуют (, чтобы упростить назначение данных узлов и предотвратить выдачу уведомлений. __isset() проверен на достоверность и вернет false соответствующим образом, хотя ) Он также реализовал ArrayAccess для доступа к данным узла и просто вернул null для отсутствующего индекса.

Я решил отказаться от этой реализации из-за накладных расходов магии PHP (, хотя я много узнал о рефакторинге / оптимизации и профилировании )

Вместо этого я использовал собственные массивы, но теперь кодовая база для моих представлений замусорена с isset(), и, честно говоря, это просто раздражает ( почти больше, чем потеря производительности вышеупомянутого осуществление )

Теперь я подумал, что самым простым решением было бы сдвинуть отметку error_reporting() вверх и вниз в зависимости от того, где мы находимся в сценарии:

// View::render()
public function render($data){
    error_reporting(E_ALL & ~E_NOTICE);
    // view generation logic
    error_reporting(-1);
}

Но это не самое чистое ( и не самое безопасное ) исправление; особенно когда вспомогательные функции вызываются в представлении. Я выбрал своего рода подход HMVC, и из представления можно выдавать подзапросы, поэтому мне нужно найти все render() точки выхода и защитить их с помощью error_reporting(-1).

У меня есть другие варианты?

Ответы [ 2 ]

3 голосов
/ 15 августа 2011

извещения «неопределенная переменная» очень ценны, даже в шаблонах представления, поскольку помогают обнаружить опечатки;но для этого необходимо либо определить каждую переменную в контроллерах, либо проверить, установлены ли они в представлениях.

Как вы заметили, два очевидных решения имеют некоторые издержки или недостатки.Даже отключение отчетов об ошибках имеет некоторые издержки, поскольку ошибки все еще генерируются (сообщение об ошибке форматируется, вызываются внутренние и пользовательские обработчики ошибок и т. Д .; они просто скрыты).И это скрывает ошибки от вспомогательных методов, которые вы можете вызывать из представлений;это не помогает при отладке.

Я бы порекомендовал вам использовать шаблонизатор.Некоторые генерируют PHP-код так же быстро, как рукописный код.Они будут обрабатывать это для вас и сделают больше (например, экранирование, ваши представления также должны быть засорены вызовами htmlspecialchars ();)).

1 голос
/ 01 ноября 2014

Продолжайте сообщать E_NOTICE, оно того стоит. Тем не менее, я согласен с тем, что Undefined Index - это не тот же калибр ошибок, что и неопределенная переменная, а isset($options['boolean_flag']) && $options['boolean_flag'] немного уродливо. Проект, над которым я работаю, содержит тысячи таких уведомлений, поэтому для того, чтобы постоянно видеть ошибки уровня E_NOTICE без затопления Undefined Index, я фактически перекомпилировал язык, чтобы игнорировать этот конкретный тип уведомлений. (Я использую HHVM, а не PHP, но это та же разница).

Да, это экстремальное решение, но это вариант в трудной ситуации. Очевидно, вы захотите использовать официальную сборку на производстве.

Примечание: я записал шаги для перекомпиляции и мог бы опубликовать это, если кто-то захочет попробовать, но это немного выходит за рамки исходного вопроса.

...