Подтвердить что ты не робот

У PHP есть оценка короткого замыкания?

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

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

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

4b9b3361

Ответ 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().

Ответ 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.