У PHP есть оценка короткого замыкания?
Учитывая следующий код:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
Если is_valid($string)
возвращает false
, интерпретатор php по-прежнему проверяет более поздние условия, например up_to_length($string)
?
Если это так, то почему он делает дополнительную работу, когда это не нужно?
Ответы
Ответ 1
Да, интерпретатор PHP "ленив", то есть он будет делать минимальное количество сравнений для оценки условий.
Если вы хотите проверить это, попробуйте следующее:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
Ответ 2
Да, это так. Здесь небольшая хитрость, которая основывается на оценке короткого замыкания. Иногда у вас может быть небольшое выражение 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) ничего не делает для изменения общего результата троичного объекта, но гарантирует, что троичное условие остается true
, игнорируя возвращаемое значение do_something()
.
Ответ 3
Некоторые чтения, чтобы согласиться со всеми этими ответами: http://en.wikipedia.org/wiki/Short-circuit_evaluation
Ответ 4
Нет, он больше не проверяет другие условия, если первое условие не выполняется.
Ответ 5
Побитовые операторы - это &
и |
.
Они всегда оценивают оба операнда.
Логическими операторами являются AND
, OR
, &&
и ||
.
- Все четыре оператора оценивают только правую сторону, если им это необходимо.
AND
и OR
имеют более низкий приоритет, чем &&
и ||
. Смотрите пример ниже.
Из руководства по PHP:
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;
В этом примере e
будет true
, а f
будет false
.
Ответ 6
Судя по моим исследованиям, в PHP, похоже, нет такого же оператора &&
как в JavaScript.
Я провел этот тест:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
и PHP 7.0.8 вернул 1
, а не Cabbage
.
Ответ 7
Нет, нет. Это всегда хорошее место для оптимизации порядка условий.
Ответ 8
Я создал свою собственную логику оценки короткого замыкания, к сожалению, это не похоже на быстрый синтаксис 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;
В качестве очень важного наблюдения при использовании Ternary Operator таким образом вы заметите, что если сравнение сделано, оно просто передаст значение этого сравнения, так как существует не просто единственная переменная. Например:
$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'
Ответ 9
Мой выбор: не доверие Оценка коротких замыканий в PHP...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
Вторая часть в условии 1 || saySomething() не имеет значения, потому что это всегда возвращает true. К сожалению saySomething() оценивается и выполняется.
Возможно, я неправильно понял точную логику коротких замыкающих выражений, но это не похоже на , "это сделает минимальное количество сравнений" для меня.
Кроме того, это не только проблема производительности, если вы выполняете присваивания внутри сравнений, или если вы делаете что-то, что имеет значение, отличное от простого сравнения, вы можете завершить разные результаты.
В любом случае... будьте осторожны.
Ответ 10
Примечание: Если вы хотите избежать ленивой проверки и выполнить каждую часть условия, в этом случае вам нужно использовать логическое И, как это:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
Это полезно, когда вам нужно, например, вызвать две функции, даже если первая возвращает false.