דָּוִדdavidov777 (daviddavidov777) wrote,
דָּוִדdavidov777
daviddavidov777

аза отдыха красноярск

В php есть интересная особенность тернарного оператора — специфический и уникальный порядок выполнения.

$ python -c "print 1 if true else 2 if true else 3 if true else 4 if true else 5"
1

$ node -e " true ? 1 : true ? 2 : true ? 3 : true ? 4 : 5"
1

$ perl -e "print true ? 1 : true ? 2 : true ? 3 : true ? 4 : 5"
1

$ ruby -e "print true ? 1 : true ? 2 : true ? 3 : true ? 4 : 5"
1

$ php -r "print true ? 1 : true ? 2 : true ? 3 : true ? 4 : 5;"
4
Java и C++ тоже вернут 1


А какая вообще разница?

Я знаю об этом интересном нюансе довольно давно, но буквально вчера обнаружил ошибку в одном из открытых исходников: автор явно не знал об этом нюансе и попался. Потому, данная статья служит всего-лишь предупреждением. Ведь, если программист ожидает от php такого же поведения, как от других языков — может попасть в халепу.

Такой приём очень удобный для задания значений, зависимо от условий. Изящная замена if-else. Например:
value = isCondFirst() ? valueFirst() :
isCondSecond() ? valueSecond() :
isCondThird() ? valueThird() :
valueDefault();

/********** Вместо **********/

if (isCondFirst()) {
value = valueFirst();
} else if (isCondSecond()) {
value = valueSecond();
} else if (isCondThird()) {
value = valueThird();
} else {
value = valueDefault();
}


Как избежать ошибки?

Первый способ — не использовать тернарный оператор в php.
Второй — прямо указывать порядок выполнения с помощью скобок:

$ php -r "print true ? 1 : (true ? 2 : (true ? 3 : (true ? 4 : 5)));"
1

Чем-то напоминает Лисп, не так ли?

Почему оно вообще так происходит?

Давайте разберемся в порядке выполнения тернарного оператора на примере JavaScript vs PHP
Напишем два тестовых скрипта, чтобы понять, как работает каждый из языков.

На всякий случай поясню, что при $foo = $lambda('fooMsg', 'fooReturn'), $foo содержит в себе функцию, которая при вызове выведет в консоль сообщение 'fooMsg' и вернет значение 'fooReturn'

$ cat ternary.js
var lambda = function (logMsg, returnValue) {
return function () {
console.log(logMsg);
return returnValue;
};
};

var cond = {
first : lambda('cond.first' , true),
second: lambda('cond.second', true),
third : lambda('cond.third' , true)
};


var value = {
first : lambda('value.first' , 'first'),
second : lambda('value.second' , 'second'),
third : lambda('value.third' , 'third'),
default: lambda('value.default', 'default')
};

console.log( 'result: ',
cond.first() ? value.first() :
cond.second() ? value.second() :
cond.third() ? value.third() : value.default()
);


$ node ternary.js
cond.first
value.first
result: first

$ cat ternary.php
$lambda('cond.first' , true),
'second'=> $lambda('cond.second', true),
'third' => $lambda('cond.third' , true),
);

$value = array(
'first' => $lambda('value.first' , 'first'),
'second' => $lambda('value.second' , 'second'),
'third' => $lambda('value.third' , 'third'),
'default'=> $lambda('value.default', 'default'),
);

echo 'result: ' . (
$cond['first']() ? $value['first']() :
$cond['second']() ? $value['second']() :
$cond['third']() ? $value['third']() : $value['default']()
) . PHP_EOL;

?>

$ php ternary.php
cond.first
value.first
value.second
value.third
result: third


Какой из этого результата можно сделать вывод. Javascript разбирает тернарный оператор вполне логично. Сначала проверяет самое левое условие. Если оно верно, то выполняет и возвращает левую часть после первого двоеточия, если не верно, то правую.
(cond.first() ? value.first() :
(cond.second() ? value.second() :
(cond.third() ? value.third() :
(value.default()))));

/********
* ===>
*/

true ? 'value.first' : /* ignored */;




Бюро активного отдыха «SamaLёt» предоставляет размещение в базах отдыха Красноярска. Базы отдыха Красноярска, описание, Цены, Условия.

Для вас базы отдыха красноярска недорого!
Tags: базы отдыха красноярска
Subscribe

  • продажа недвижимости, дачные дома

    The Guardian обратила внимание на то, что социальные сети могут использоваться не только как информационный канал для революций и потрясений, а для…

  • New age.................

    Заниматься еще больше торговлей!Понять куда пойдет тренд. Учиться , как можно больше задавать как можно больше вопросов.не терять время на всякую…

  • music

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments