PHP короткий, если поведение

Возможный дубликат:
Как я могу понимать вложенные операторы ?: в PHP?

Почему это:

  $object->customer->phone =
          ! empty( $object->customer->address->phone_fixed ) ?
                    $object->customer->address->phone_fixed :
          ! empty( $object->customer->address->phone_mobile ) ?
                    $object->customer->address->phone_mobile :
          ! empty( $object->customer->address->phone_business ) ?
                    $object->customer->address->phone_business : '';

возвращает $object->customer->address->phone_business, даже если $object->customer->address->phone_fixed установлено и не пусто?

Спасибо.


person cili    schedule 06.07.2012    source источник
comment
Короткий синтаксис if является левоассоциативным.   -  person Mihai Stancu    schedule 06.07.2012


Ответы (4)


Это связано с ассоциативностью тернарного оператора. Я бы как минимум добавил скобки в ваш код; но, честно говоря... более чем одна тройка в одном утверждении - это современная оплошность. Интересная ссылка

person Chris Trahey    schedule 06.07.2012
comment
+1 Хорошая, интересная ссылка. Забыл о печали PHP - person Jason McCreary; 06.07.2012
comment
Спасибо, я провел рефакторинг с помощью if/elseif. - person cili; 06.07.2012

Либо ваши данные не то, что вы думаете (отладьте, чтобы увидеть), либо ваша логика неверна.

Хотя этот краткий if (тернарный оператор) подходит для простого встроенного присваивания, я бы посоветовал вам реорганизовать его в блоки if/else для ясности.

Я думаю, как только вы это сделаете, ваша проблема станет ясной. И, в свою очередь, докажите, что нужно писать чистый код.

person Jason McCreary    schedule 06.07.2012
comment
-1 Короткий синтаксис if является левоассоциативным. - person Mihai Stancu; 06.07.2012
comment
Никогда не говорил иначе. Почему бы вам не опубликовать ответ вместо того, чтобы голосовать за других. В любом случае, это подпадает под неправильное использование кода и, следовательно, подпадает под действие ваша логика неверна :) - person Jason McCreary; 06.07.2012
comment
Потому что это повторяющийся вопрос, на который я уже ответил где-то еще. Я не хочу копировать и вставлять свой ответ, потому что это тоже неконструктивно. ТАК хочет, чтобы на один вопрос на сайте был дан ответ только один раз. - person Mihai Stancu; 06.07.2012
comment
Тогда вы должны были оставить комментарий со ссылкой на эту конкретную тему, а не просто подбирать ответы в этой теме с отрицательным комментарием для совершенно законных и подходящих ответов. Невежливо отвергать попытки других людей дать рекомендации и советы по вопросам, связанным с вопросами. Четкий +1 от меня по этому ответу просто ради справедливости. - person brezanac; 06.07.2012
comment
@Mihai Stancu, понял о дублировании. Я закрыл многие вопросы как таковые. Однако я не верю в голосование против. Особенно, когда ответ не является ни неправильным, ни вводящим в заблуждение. - person Jason McCreary; 06.07.2012
comment
@holodoc, спасибо за справедливость. - person Jason McCreary; 06.07.2012
comment
@holodoc Я действительно оставил комментарий к исходному вопросу со ссылкой на дубликат. Переполнение стека позволяет нам выбирать, как нам себя вести, и я предпочитаю голосовать против ответов, которые решают побочные проблемы, даже если ответы верны по отношению к побочным проблемам. Я считаю, что мое поведение помогает Stack Overflow сортировать ответы «хороший-лучший-лучший» и показывать следующим 100 посетителям сначала наиболее релевантные ответы. - person Mihai Stancu; 07.07.2012
comment
@Mihai Stancu, вы действительно имеете право вести себя на SO так, как хотите. Однако, учитывая мою репутацию и поддержку моего ответа и оригинального комментария, я четко знаю, как работает SO. Кроме того, не является побочным вопросом предоставление рекомендаций в виде ответа в стиле научите человека ловить рыбу. Иногда лучший ответ не тот, который решает проблему. Отсюда и система голосования. Возможно, вам следует подумать об этом, прежде чем голосовать против ответов. Ваши многочисленные комментарии и предложение закрыть вопрос более чем достаточно. Голосование против приносит негатив. Такое поведение не помогает. - person Jason McCreary; 07.07.2012
comment
С вашим опытом SO это не должно создавать для вас негатива. Я проголосовал за @ctrahey за актуальность и проголосовал против вас за меньшую актуальность. Как вы, вероятно, испытали во многих местах, это не личное дело, это вопрос (оправданного) мнения. - person Mihai Stancu; 07.07.2012
comment
Я не принимаю ничего личного. Я не согласен с вашим поведением, когда вы голосуете за один ответ и против остальных как менее актуальных. Такое поведение, несомненно, является негативным и явно обескураживает SO - тем фактом, что голосование против также влияет на вашу репутацию. - person Jason McCreary; 07.07.2012
comment
Тот факт, что это подрывает мою репутацию, не является отражением того, что SO обескураживает меня, это отражение ответственности совести, которую я должен посвятить тому факту, что я с чем-то не согласен. - person Mihai Stancu; 08.07.2012
comment
Также я не отрицал все остальные ответы, а только те, которые были не на правильном пути (предлагая правильную, но побочную поддержку). И я проголосовал за @ctrahey за то, что это единственный правильный ответ. - person Mihai Stancu; 08.07.2012

Скорее всего, переменные не содержат того, что вы думаете, используйте var_dump и выполните некоторую отладку.

Я даже не знал, что вы можете использовать elseif, используя короткое поведение. На вашем месте я бы просто переписал этот кусок кода, чтобы сделать его более читабельным/надежным/предсказуемым и т.д.

На мой взгляд, простое написание нескольких if выглядело бы намного лучше, и любой, кто читал бы код, сразу бы его понял.

// Извините, что не ответил на вопрос.

person 472084    schedule 06.07.2012
comment
-1 Короткий синтаксис if является левоассоциативным. - person Mihai Stancu; 06.07.2012
comment
Я хочу сказать, что вы не прилагаете усилий, чтобы на самом деле ответить на вопрос. Вы просто предлагаете совет о том, как подойти и избежать ситуации. Что должно быть комментарием, а не ответом. - person Mihai Stancu; 06.07.2012
comment
Я имел в виду вашу точку зрения относительно левой ассоциативности, неважно. - person 472084; 06.07.2012

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

Я бы рекомендовал использовать несколько операторов if/else или switch.

if (!empty($object->customer->address->phone_fixed)
    $object->customer->phone = $object->customer->address->phone_fixed;
elseif (!empty($object->customer->address->phone_mobile)
    $object->customer->phone = $object->customer->address->phone_mobile;
elseif (!empty($object->customer->address->phone_business)
    $object->customer->phone = $object->customer->address->phone_business;
person Joshua Dickerson    schedule 06.07.2012