Сотрудник несколько раз добавлял команду assert в наши библиотеки в тех местах, где я бы использовал оператор if и выдал исключение. (До этого я даже не слышал об assert.) Вот пример того, как он это использовал:
assert('isset($this->records); /* Records must be set before this is called. */');
Я бы сделал:
if (!isset($this->records)) {
throw new Exception('Records must be set before this is called');
}
Из прочтения документации PHP по assert кажется, что рекомендуется убедиться, что assert активен, и добавить обработчик перед использованием assert. Я не могу найти место, где он это сделал.
Итак, мой вопрос: я использую assert как хорошую идею, учитывая вышеизложенное, и должен ли я использовать его чаще вместо if и исключений?
Еще одно замечание: мы планируем использовать эти библиотеки в различных проектах и на серверах, включая проекты, в которых мы, возможно, даже не участвуем (библиотеки с открытым исходным кодом). Есть ли разница в использовании assert?
'isset
(строчка с кодомassert
)? Не простоisset
(без кавычек'
)?Ответы:
Эмпирическое правило, которое применимо к большинству языков (все, что я смутно знаю), заключается в том, что
assert
используется, чтобы утверждать, что условие всегда истинно, тогда как anif
подходит, если возможно, что оно иногда терпит неудачу.В этом случае я бы сказал, что
assert
это уместно (исходя из моего слабого понимания ситуации), потому что он всегдаrecords
должен быть установлен до вызова данного метода. Таким образом, неспособность установить запись будет скорее ошибкой в программе, чем условием выполнения. Здесь это помогает гарантировать (при соответствующем тестировании), что нет возможного пути выполнения программы, который мог бы вызвать вызов кода, который защищен с помощью , без установки.assert
assert
records
Преимущество использования
assert
в отличие от использованияif
заключается в том, чтоassert
его можно отключить в производственном коде, что снижает накладные расходы. Ситуации, с которыми лучше всего справиться,if
могут возникнуть во время выполнения в производственной системе, и поэтому ничего не теряется из-за невозможности их выключить.источник
assert_options(ASSERT_BAIL)
. Это быстрее, чем вручную, если / все равно обходные пути.Думайте об утверждениях как о «властных комментариях». Вместо комментария вроде:
// Note to developers: the parameter "a" should always be a number!!!
использование:
assert('is_numeric(a) /* The parameter "a" should always be a number. */');
Значения точно такие же и предназначены для одной и той же аудитории, но первый комментарий легко забыть или проигнорировать (независимо от того, сколько восклицательных знаков), в то время как «мощный комментарий» доступен не только для чтения и понимания людьми, он также постоянно тестируется на компьютере во время разработки и не будет проигнорирован, если вы настроите хорошую обработку assert в коде и в рабочих привычках.
С этой точки зрения утверждения - это совершенно другая концепция, чем if (error) ... и исключения, и они могут сосуществовать.
Да, вы должны комментировать свой код, и да, вы должны использовать «мощные комментарии» (утверждения), когда это возможно.
источник
Это полностью зависит от вашей стратегии развития. Большинство разработчиков не знают
assert()
и используют последующее модульное тестирование. Но проактивные и встроенные схемы тестирования иногда могут быть полезными.assert полезен, потому что его можно включать и отключать. Это не снижает производительность, если такой обработчик утверждения не определен. У вашего коллеги его нет, и вам следует разработать код, который временно включает его в среде разработки (если включены E_NOTICE / E_WARNING, то должен быть обработчик утверждения). Я использую его иногда, когда мой код не может принять смешанные типы переменных - обычно я не использую строгую типизацию в слабо типизированном PHP, но есть случайные варианты использования:
function xyz($a, $b) { assert(is_string($a)); assert(is_array($b));
Что, например, компенсировало бы отсутствие спецификаторов типа
string $a, array $b
. PHP5.4 их поддерживает, но не проверяет.источник
Assert не заменяет обычное управление потоком, такое как
if
или исключения, потому что оно предназначено только для отладки во время разработки.источник
Важное замечание относительно assert в PHP более ранних версий, чем 7. В отличие от других языков с конструкцией assert, PHP не выводит утверждения assert полностью - он обрабатывает их как функцию (выполните debug_backtrace () в функции, вызываемой утверждением). Отключение утверждений, кажется, просто заставляет функцию ничего не делать в движке. Обратите внимание, что PHP 7 можно заставить эмулировать это поведение, установив для zend.assertions значение 0 вместо более обычных значений 1 (включено) или -1 (выключено).
Проблема возникает в том, что assert будет принимать любой аргумент, но если аргумент не является строкой, тогда assert получает результаты выражения независимо от того, включен ли assert или нет. Вы можете проверить это с помощью следующего блока кода.
<?php function foo($a) { echo $a . "\n"; return TRUE; } assert_options(ASSERT_ACTIVE, FALSE); assert( foo('You will see me.')); assert('foo(\'You will not see me.\')'); assert_options(ASSERT_ACTIVE, TRUE); assert( foo('Now you will see')); assert('foo(\'both of us.\')');
Учитывая намерение assert, это ошибка, причем давно существующая, поскольку она присутствует в языке с тех пор, как assert был введен еще в PHP 4.
Строки, передаваемые в assert, оцениваются со всеми вытекающими из этого последствиями для производительности и опасностями, но это единственный способ заставить операторы assert работать так, как они должны работать в PHP (это поведение устарело в PHP 7.2).
РЕДАКТИРОВАТЬ: Изменено выше, чтобы отметить изменения в PHP 7 и 7.2
источник
zend.assertions
настройка ini на полное отключениеassert()
.Assert следует использовать только в разработке, так как это полезно для отладки. Поэтому, если вы хотите, вы можете использовать их для разработки своего веб-сайта, но вы должны использовать исключения для действующего веб-сайта.
источник
Нет, ваш коллега не должен использовать его в качестве обработчика ошибок общего назначения. Согласно инструкции:
Если вы знакомы с автоматизированными наборами тестов, глагол assert обычно используется для проверки вывода некоторых методов или функций. Например:
function add($a, $b) { return $a + $b; } assert(add(2,2) == 5, 'Two and two is four, dummy!'); assert(is_numeric(add(2,2)), 'Output of this function to only return numeric values.');
Ваш коллега не должен использовать его в качестве обработчика ошибок общего назначения и в данном случае для проверки ввода. Похоже, что поле записей может не быть установлено каким-либо пользователем вашей библиотеки.
источник
Ваш коллега действительно пытается применить дизайн по контракту (DbC) на языке Eiffel на основе книги: Object Oriented Software Construction, 2nd Edition.
Утверждение в том виде, в каком он его использовал, было бы {P} -частью логики Хора или тройки Хора: {P} C {Q}, где {P} - это предусловие assert (ion) s, а {Q} - постусловие assert (ion) s.
Я бы критически отнесся к советам, которые давались по поводу ошибок в функции assert в PHP. Вы не хотите использовать код с ошибками. На самом деле вам нужно, чтобы создатели PHP исправили ошибку в assert. Пока они этого не сделают, вы можете использовать assert, но с учетом его текущего состояния с ошибками.
Более того, если функция assert содержит ошибки, я предлагаю вам не использовать ее в производственном коде. Тем не менее, я рекомендую вам использовать его при разработке и тестировании кода, где это необходимо.
Наконец, если вы изучите проектирование по контракту, вы обнаружите, что есть последствия использования логических утверждений в свете объектно-ориентированного классического наследования, то есть вы никогда не должны ослаблять предусловие или постусловие. Это может быть опасно для ваших полиморфных объектов-потомков, взаимодействующих друг с другом. Пока вы не поймете, что это значит - я оставлю это в покое!
Более того - я настоятельно рекомендую разработчикам PHP провести всестороннее изучение дизайна по контракту и попытаться как можно скорее включить его в PHP! Тогда все мы можем извлечь выгоду из наличия компилятора / интерпретатора с поддержкой DbC, который справился бы с проблемами, указанными в ответах (выше):
ПРИМЕЧАНИЕ. Даже использование
if
-statement в качестве замены assert (предусловия) будет иметь ужасные последствия, если используется для усиления предусловия или ослабления постусловия. Чтобы понять, что это значит, вам нужно будет изучить дизайн по контракту, чтобы знать это! :-)Удачи в учебе и учебе.
источник