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

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 ответа

Решение

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

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

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

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

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

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

Другие вопросы по тегам