Условное присвоение значений PHP - PullRequest
20 голосов
/ 02 декабря 2010

Для очень распространенного случая присвоения значения переменной на основе результата выражения я фанат троичных операторов:

$foo = $bar ? $a : b;

Однако, если $ bar является относительно дорогой операцией, и я хочу присвоить результат $ bar переменной $ foo, если результат верный, это неэффективно:

$foo = SomeClass::bigQuery() ? SomeClass::bigQuery() : new EmptySet();

Один из вариантов:

$foo = ($result = SomeClass::bigQuery()) ? $result : new EmptySet();

Но я бы предпочел, чтобы в памяти не осталось лишних $result.

Лучший вариант, который у меня есть:

$foo = ($foo = SomeClass::bigQuery()) ? $foo : new EmptySet();

Или без троичных операторов:

if(!$foo = SomeClass::bigQuery()) $foo = new EmptySet();

Или, если операторы потока программ не в вашем стиле:

($foo = SomeClass::bigQuery()) || ($foo = new EmptySet());

Так много вариантов, ни один из них не является действительно удовлетворительным. Что бы вы использовали, и я что-то упускаю здесь действительно очевидное?

Ответы [ 4 ]

38 голосов
/ 02 декабря 2010

В PHP 5.3 введен новый синтаксис для решения именно этой проблемы:

$x = expensive() ?: $default;

См. Документацию :

Начиная с PHP 5.3, можно опустить среднюю часть троичного оператора.
Выражение expr1 ?: expr3 возвращает expr1, если expr1 равно TRUE, а expr3 в противном случае.

8 голосов
/ 02 декабря 2010

Можете ли вы обновить SomeClass: bigQuery (), чтобы он возвращал новый EmptySet () вместо false?

Тогда у вас просто есть

$foo = SomeClass::bigQuery();
1 голос
/ 02 декабря 2010

Небольшое изменение вашего последнего варианта:

$ foo = SomeClass :: bigQuery () или new EmptySet (); на самом деле это не работает, спасибо, что заметили.

Часто используется в сочетании с кодом MySQL, но, кажется, всегда забывается в сопоставимых ситуациях:

$result = mysql_query($sql) or die(mysql_error());

Хотя лично я предпочитаю тот, который вы уже упомянули:

if(!$foo = SomeClass::bigQuery())
    $foo = new EmptySet();
1 голос
/ 02 декабря 2010
$foo = SomeClass::bigQuery();
if (!$foo) $foo = new EmptySet();

Редакция вторая, credit @ meagar

...