Помогите разобраться: строка PHP

Тема в разделе "PHP", создана пользователем Den1xxx, 11 фев 2017.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Den1xxx

    Den1xxx

    Moderator
    Регистр.:
    15 янв 2014
    Сообщения:
    280
    Симпатии:
    155
    Что здесь происходит?
    PHP:
    isset($m[$e[$pk]]) ?: $m[$e[$pk]] = array();
    Не совсем понятен оператор «?:» и последующее присвоение.

    Я правильно понимаю, что здесь проверяется существование $m[$e[$pk]] и если его нет — определяется как пустой массив?

    Я всегда встречал это в контексте присвоения в начале, например так
    PHP:
    $m[$e[$pk]] = isset($m[$e[$pk]]) ?: array();
    и даже так было бы понятнее и привычнее.

    Тогда я могу переписать это так:
    PHP:
    if(!isset($m[$e[$pk]])) $m[$e[$pk]] = array();
    Количество символов то же, а работать будет так же?

    Если это так, то в данном случае автор не сэкономил ни символа, однако дал -200 к понятности и сломал совместимость к PHP<5.3

    Код отсюда https://3v4l.org/s2PNC
     
  2. UJy

    UJy

    Регистр.:
    23 авг 2011
    Сообщения:
    380
    Симпатии:
    134
    Да, вы совершенно правы. И ваши оба варианта написания аналогичны по смыслу первому варианту.

    Вообще тернарные операторы достаточно сильно сокращают код, но использовать их стоит с умом ибо путаницы в логику они вносят преизрядно...
     
    Den1xxx нравится это.
  3. Den1xxx

    Den1xxx

    Moderator
    Регистр.:
    15 янв 2014
    Сообщения:
    280
    Симпатии:
    155
    Ну я когда подучил тернарные операторы, тоже много где применяю.
    И иногда намного понятнее получается, чем if, часто просто короче.
    Для того же, чтобы уверенно писать конструкцию, что я привёл, программист на 100% должен быть уверен, что порядок выполнения пойдёт по правильному пути.
    Я в этом случае был не уверен.
    Если уж «обфусцировать», то для уверенности я бы написал так:
    PHP:
    isset($m[$e[$pk]]) ?: ($m[$e[$pk]] = array());
    И тогда бы на 100% был бы уверен, что порядок выполнения будет соблюден, как задумано.

    А вот так работает под всеми версиями PHP, даже от 3:
    https://3v4l.org/Uq0O5
     
    Последнее редактирование: 11 фев 2017
  4. Casper_R

    Casper_R Создатель

    Регистр.:
    3 май 2007
    Сообщения:
    87
    Симпатии:
    31
    так то больше на бред смахивает. конструкция:
    PHP:
    $m[$e[$pk]] = isset($m[$e[$pk]]) ?: array();
    в случае существования переменной $m[$e[$pk]], просто присвоит ей true, что перезапишет изначальное значение переменной ... что то я не улавливаю прикладной смысл.

    если уж и использовать, то без isset:
    PHP:
    $m[$e[$pk]] = $m[$e[$pk]] ?: array();
    так значение переменной не будет перезаписано на булевый тип.

    А вообще, тернарные операторы удобно использовать в ретёрнах:
    PHP:
    return $result ?: false;
     
  5. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.611
    Симпатии:
    1.539
    Мы таким образом избегаем ошибок типа Notice, хотя в данном примере это не будет заметно, но возможно программист привык уже так писать и делает не задумываясь.

    Два кода для сравнения:
    PHP:
    <?php
    error_reporting
    (E_ALL E_NOTICE);
    $m $m ?: array();
    Notice: Undefined variable: m in /in/8gtk8 on line 3

    PHP:
    <?php
    error_reporting
    (E_ALL E_NOTICE);
    isset(
    $m) ?: $m = array();
    выполнится без ошибок

    В конструкции if(!isset( , очень легко пропустить восклицательный знак ! и убить потом очень много времени на поиск ошибки. Тернарный в данном случае нагляднее. Писать в одну строку и без фигурных скобок if, сейчас тоже не популярно, примерно из тех же соображений.

    Чаще всего встречается через
    PHP:
    $m = isset($m) ? $m : array();
    Но тут несколько лишних символов.

    PS https://3v4l.org/Uq0O5 функция рекурсии ужасна (слишком много аргументов), при рефакторинге потратите дофига времени чтобы понять как это работает. Там действительно нужен настолько универсальный комбайн и это нельзя разбить на несколько этапов?
     
    timur_ и NULLED555 нравится это.
Статус темы:
Закрыта.