У PHP есть оценка короткого замыкания? - PullRequest
64 голосов
/ 17 апреля 2011

Учитывая следующий код:

if (is_valid($string) && up_to_length($string) && file_exists($file)) 
{
    ......
}

Если is_valid($string) возвращает false, проверяет ли php-интерпретатор более поздние условия, например up_to_length($string)?
Если так, то почемуделать дополнительную работу, когда это не нужно?

Ответы [ 8 ]

91 голосов
/ 17 апреля 2011

Да, интерпретатор PHP «ленив», то есть он будет выполнять минимальное число сравнений, возможных для оценки условий.

Если вы хотите это проверить, попробуйте следующее:

function saySomething()
{
    echo 'hi!';
    return true;
}

if (false && saySomething())
{
    echo 'statement evaluated to true';
}
8 голосов
/ 09 марта 2017

Да, это так.Вот небольшая хитрость, которая основывается на оценке короткого замыкания.Иногда у вас может быть небольшое выражение 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().

2 голосов
/ 17 апреля 2011

Нет, другие условия больше не проверяются, если первое условие не выполняется.

0 голосов
/ 11 июля 2019

Судя по моим исследованиям, PHP, похоже, не имеет такого же оператора короткого замыкания &&, как JavaScript.

Я провел этот тест:

$one = true;

$two = 'Cabbage';

$test = $one && $two;

echo $test;

и PHP 7.0.8 вернул 1, а не Cabbage.

0 голосов
/ 24 января 2017

В итоге, следовательно:

Битовые операторы есть & и |
Они всегда оценивают оба операнда.

Логические операторы - И, ИЛИ, && и ||
И и ИЛИ всегда оценивают оба операнда.

&& и || оценивать только правую сторону, только если это необходимо.

0 голосов
/ 30 ноября 2015

Я создал свою собственную логику оценки короткого замыкания, к сожалению, это не что иное, как быстрый синтаксис 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'
0 голосов
/ 29 апреля 2015

Примечание: Если вы хотите избежать ленивой проверки и выполнить каждую часть условия, в этом случае вам нужно использовать логическое И, например:

if (condition1 & condition2) {
 echo "both true";
}
else {
 echo "one or both false";
}

Это полезно, когда вам нужно, например, вызвать две функции, даже если первая вернула false.

0 голосов
/ 14 января 2012

Мой выбор: не доверять оценке короткого замыкания в PHP ...

function saySomething()
{
    print ('hi!');
    return true;
}

if (1 || saySomething())
{
    print('statement evaluated to true');
}

Вторая часть в условии 1 ||saySomething () не имеет значения, потому что это всегда будет возвращать true.К сожалению, saySomething () оценивается и выполняется.

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

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

В любом случае ...будь осторожен.

...