2013-12-15 2 views
0

У меня есть метод, как это:Guarding мои методы против плохих входных

public function create (array $hash) { 
    $id = $hash[ID_KEY]; 
    $this->store[$id] = $hash; 
} 

Я хочу, чтобы уберечь ее от ошибок, вызванных плохим входом. Например, мой код может ошибочно передать $hash с

$id = '' or $id = null, 

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

if (! $id) throw new Exception("Hash with empty id"); 

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

Проблема в том, что существует много таких методов. Действительно ли лучше всего защищать каждый из них за каждый аргумент, который может стать null, но не должен?

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

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

EDIT. Я поставил больше стражей и действительно обнаружил несколько ошибок, которые я бы не нашел иначе. Также мои тесты не заметили их.

Кроме того, это помогло лучше понять роль методов чтения - вернуть значение, если найдено или return empty Array если нет. Вход $id = null не соответствует не найден и, следовательно, также возвращается empty Array. Таким образом, метод является чистым и последовательным.

+1

Это зависит от вас, насколько вы осторожны. Я не думаю, что большинство программистов ставят множество охранников, как это, они стараются в первую очередь называть свои функции. – Barmar

+0

@Barmar Я пробовал именно это и в конечном итоге мучительно тратил слишком много времени на поиски ошибок. :( –

+0

Тогда вперед, поставьте страж в начале каждой функции. – Barmar

ответ

2

Вы можете использовать PHP is_null() и empty(), чтобы легко управлять этим видом вывода. Также я предлагаю вам написать список функций, используемых только в debug (поскольку вы хотите совершенствовать свой код). Вызовите эту функцию в каждом методе, который вы хотите протестировать, и установите константу, как DEBUG_MODE, чтобы обрабатывать поведение функций отладки. Все это можно было бы сделать, используя unit testing, что потребует большего внимания и времени. Но если у вас есть или вы хотите узнать что-то новое, модульное тестирование, безусловно, лучший выбор.

Также это хорошая практика для обработки ВСЕХ СЛУЧАЙ, о которых вы можете думать. Например, если ваш «метод чтения» ожидает, что он не найдет нулевое значение (поскольку вы считаете, что его нет, потому что вы устранены путем тестирования тестирования), если этот «метод чтения» обнаруживает нулевое значение «уродливой» ошибки PHP будет отображаться где-то, или, что еще хуже, если ошибка_репортажа закрыта, вы, возможно, никогда не увидите проблемы или, что еще хуже, код может продолжить выполнение и полностью повредить дальнейшие данные.

+0

Спасибо, это дает мне больше веры в то, что я не действую как навязчивый маньяк-пу все эти охранники. :) Мои методы чтения выводят пустые строки, чтобы пометить конец списка, поэтому, если это сделано плохо, метод получателя будет считать, что список окончен, и данные будут пропущены без каких-либо примечаний. Довольно противный. Поэтому, я думаю, я застрял с охранниками. Да, я использовал тесты и думал, что они в основном заменяют режим _debug_, я могу переосмыслить его, хотя ... –

+0

Относительно ** режима отладки ** - мой код - демон cron, поэтому я полагаю, что я всегда должен его хранить в режиме _debug_, чтобы увидеть ошибки. –

+0

Ну, переменная switch bool всегда рекомендуется, я думал, вам нужно отлаживать ваш код только раз в то время, а затем отключить «режим отладки». Для этого я бы добавил, что добавление функции заголовка к каждой функции будет немного чрезмерно, а использование исключений будет довольно быстрым и полезным. Хотя вы можете комбинировать оба и иметь некоторые функции, которые помогут вам бросать исключения (например, я предложил в своем ответе). Также напомните, что вы можете расширить базовые [** Исключения **] (http://www.php.net/manual/it/language.exceptions.extending.php), чтобы настроить поведение вашего кода. – Kei

Смежные вопросы