Учитывая следующий код:
if (is_valid($string) && up_to_length($string) && file_exists($file)) { ...... }
Если is_valid($string)
возвращает false, интерпретатор php все еще проверяет более поздние условия, такие как up_to_length($string)
? Если да, то почему это делает дополнительную работу, когда это не нужно?
Да, интерпретатор PHP «ленив», то есть он будет делать минимальное количество сравнений для оценки условий.
Если вы хотите проверить это, попробуйте следующее:
function saySomething() { echo 'hi!'; return true; } if (false && saySomething()) { echo 'statement evaluated to true'; }
Некоторые чтения, чтобы согласиться со всеми этими ответами: http://en.wikipedia.org/wiki/Short-circuit_evaluation
Да. Вот небольшой трюк, который опирается на оценку короткого замыкания. Иногда у вас может быть небольшой оператор if, который вы предпочитаете писать как тройной, например:
if ($confirmed) { $answer = 'Yes'; } else { $answer = 'No'; }
Может быть переписано как:
$answer = $confirmed ? 'Yes' : 'No';
Но тогда, если блок yes также потребовал выполнения какой-либо функции?
if ($confirmed) { do_something(); $answer = 'Yes'; } else { $answer = 'No'; }
Ну, переписывание как тройной все еще возможно, из-за короткого замыкания:
$answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';
В этом случае выражение (do_something () || true) не делает ничего, чтобы изменить общий результат тройного, но гарантирует, что do_something () будет запущен, только если $ подтверждено true.
Нет, он больше не проверяет другие условия, если первое условие не выполняется.
Я создал свою собственную логику оценки короткого замыкания, к сожалению, это не похоже на быстрый синтаксис javascripts, но, возможно, это решение, которое может оказаться полезным:
$short_circuit_isset = function($var, $default_value = NULL) { return (isset($var)) ? : $default_value; }; $return_title = $short_circuit_isset( $_GET['returntitle'], 'God'); // Should return type 'String' value 'God', if get param is not set
Я не могу вспомнить, откуда я получил следующую логику, но если вы выполните следующее;
(isset($var)) ? : $default_value;
Вы можете пропустить, чтобы снова написать истинную переменную условия после знака вопроса, например:
(isset($super_long_var_name)) ? $super_long_var_name : $default_value;
Как очень важное замечание , при использовании Тернарного оператора таким образом вы заметите, что если сравнение сделано, оно просто передаст значение этого сравнения, так как существует не только одна переменная. Например:
$num = 1; $num2 = 2; var_dump( ($num < $num2) ? : 'oh snap' ); // outputs bool 'true'
Таким образом:
Побитовые операторы: & и |
Они всегда оценивают оба операнда.
Логическими операторами являются AND, OR, && и ||
AND и OR всегда оценивают оба операнда.
&& и || оценивайте только правую сторону, если это необходимо.
Нет, нет. Это всегда хорошее место для оптимизации порядка условий.
Замечание: если вы хотите избежать ленивой проверки и выполнить каждую часть условия, в этом случае вам нужно использовать логическое И, как это:
if (condition1 & condition2) { echo "both true"; } else { echo "one or both false"; }
Это полезно, когда вам нужно, например, вызвать две функции, даже если первая возвращает false.
Мой выбор: не доверяйте оценке Short Circuit в PHP …
function saySomething() { print ('hi!'); return true; } if (1 || saySomething()) { print('statement evaluated to true'); }
Вторая часть в условии 1 || saySomething () не имеет значения, потому что это всегда возвращает true. К сожалению saySomething () оценивается и выполняется.
Возможно, я неправильно понял точную логику коротких замыканий, но это не похоже на то, что «это сделает минимальное количество сравнений» для меня.
Более того, это не только проблема производительности, если вы выполняете задания внутри сравнений, или если вы делаете что-то, что имеет значение, отличное от простого сравнения, вы можете положить конец другим результатам.
В любом случае … будьте осторожны.