За последние 24 часа нас посетили 15008 программистов и 1759 роботов. Сейчас ищут 1525 программистов ...

Что означает такая запись условия?

Тема в разделе "PHP для новичков", создана пользователем noindex, 15 фев 2018.

  1. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Господа, всем доброго вечера.

    Разбираю глюки в функционале, и наткнулся на такое условие в цикле:

    PHP:
    1. if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation)))
    2. continue;
    Я как бы не совсем уж чайник, понимаю что в $arrObjectParentRelation прописывается результат выполнения функции parseChildRelationOfParentsString.
    Так же понимаю что при определенном условии срабатывает continue и цикл переходит к следующей итерации.

    НО, я не могу понять что проверяет такое условие, т.к. привык работать с простым форматом условий %)

    Проблема в том что continue срабатывает тогда, когда не должен, если его закомментить, то всё начинает работать, но я боюсь что просто не понимаю всей величины замысла разработчика и просто закомментив строку, я получу баг.


    PHP:
    1. $arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation);
    2. print_r(arrObjectParentRelation);
    Возвращает массив со значениями...

    Что проверяется в этом условии и при каком раскладе условие срабатывает?

    Спасибо!
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.787
    Симпатии:
    1.328
    Адрес:
    Лень
  3. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    если в результате присвоения переменной результата выполнения функции в переменной окажется логически ложный результат - пропустить итерацию.
    (иначе - работать с этим результатом)
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.787
    Симпатии:
    1.328
    Адрес:
    Лень
    уверен ?
     
  5. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    А что в данном случае логически ложный результат?
    Переменная ранее не объявляется, соответственно тип не указан или речь не о типах данных?

    Уверен 100%
    Вот код в этом же цикле:
    PHP:
    1. $checkResult = self::parseChildRelationOfParentsString($objectParentRelation);
    2.                 echo "Результат parseChildRelationOfParentsString <br /> <pre>";
    3.                 print_r($checkResult);
    4.                 echo "</pre>";
    Возвращает:
    http://prntscr.com/if61xd
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.787
    Симпатии:
    1.328
    Адрес:
    Лень
    ты мне сейчас показал совсем другой код,
    --- Добавлено ---
    PHP:
    1. $arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation);
    2. print_r(arrObjectParentRelation);
    ?
    --- Добавлено ---
    если объект пустой то TRUE
    --- Добавлено ---
    тоже самое
    if ( empty ( $arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation) ) )
    {}
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    именно поэтому так лучше не писать
     
  8. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @noindex, откройте уже для себя "Операторы" и, в частности "оператор присваивания".
     
  9. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.575
    Симпатии:
    1.759
    Это азы. php трактует как ложь: false, null, 0, 0.0, [] (пустой массив), "" (пустую строку), а так же (и это сюрприз от разрабов PHP и источник трудно находимых ошибок) "0" (строку, в которой записан символ 0).

    Оператор присвоения возвращает присвоенное значение, что позволяет писать цепочки присвоений ($a = $b = $c = $d = 255;), а также вот такие условия
    Это понятно всем, кто знает язык, поэтому почему бы не попользоваться возможностью?
     
  10. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    потому что это не очевидная запись. это увеличивает риски ошибок. а так делать не надо. конец.
     
    noindex нравится это.
  11. Abyss

    Abyss Старожил

    С нами с:
    12 дек 2015
    Сообщения:
    1.298
    Симпатии:
    218
    Адрес:
    Default city
    Субъективненько, но можно и вынести из условия.
     
  12. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @igordata то есть... while (false !== ($entry = readdir($handle))) в миг стало говнокодом? Охуенно, чо!
     
    Abyss нравится это.
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    по мне так она всегда им была
     
  14. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Ну так естественно, в первом сообщении код с условием, а это код над условием для проверки того что parseChildRelationOfParentsString возвращает массив.

    Я тоже так думал, но тогда оно не должно сработать при наличии массива в возвращаемых данных %)
    Ыот я и подумал что чего-то недопонимаю...

    Да не то слово... но что есть то есть.

    Ну я как бы знаю что означает '=' :)
    Вопрос из-за того что условие ведет себя аномально для моего понимания.

    Хм.

    Тут дело стало интереснее.

    Вот весь код цикла:

    PHP:
    1. foreach ($arrPosts as $keyPost => $pPost)
    2.             {
    3.                 $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru'));              
    4.  
    5.                 if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null)))
    6.                     $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord;
    7.  
    8.                 if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null)))
    9.                     continue;
    10.  
    11.                 if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation)))
    12.                 continue;
    13.  
    14.                 foreach ($arrObjectParentRelation as $keyParentId => $arrChildData)
    15.                     if (!in_array($keyParentId, $arrPostsIds))
    16.                         unset($arrObjectParentRelation[$keyParentId]);
    17.  
    18.                 $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation;
    19.             }
    Если закомментить второй continue - код начинает работать правильно (в том месте, в которое смотрю для правки).

    Соответственно, делаю вывод - в какой-то итерации условие перед вторым continue не срабатывает ($objectParentRelation пустой).
    Беру и тупо меняю второй continue на echo "!!!"; - он не срабатывает...
    Т.е. !!! не выводится и логика в том месте где я смотрю работает ошибочно, т.е. аналогино наличию continue %)

    Может тут проблема не в логике, а в синтаксисе, который например начал иначе интерпритироваться на новой версии php?
    В частности отсутствие фигурных скобок в циклах и условиях...
     
  15. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @noindex, добавьте перед проверкой вывод значения $arrMetas['object_parent_relation'] (с предварительной проверкой на isset), а в if - тот самый echo '!!!'.
    Заодно и узнаете, какое не приводимое к false значение принимает $objectParentRelation.
     
  16. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Легко.
    PHP:
    1. foreach ($arrPosts as $keyPost => $pPost)
    2.             {
    3.                 $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru'));
    4.                
    5.                 if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null)))
    6.                     $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord;
    7.  
    8.                 if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null)))
    9.                     continue;
    10.                 if (isset($arrMetas['object_parent_relation'])){
    11.                     print_r($arrMetas['object_parent_relation']);  
    12.                 }
    13.                
    14.                 if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation)))
    15.                 echo "!!!";
    16.  
    17.                 foreach ($arrObjectParentRelation as $keyParentId => $arrChildData)
    18.                     if (!in_array($keyParentId, $arrPostsIds))
    19.                         unset($arrObjectParentRelation[$keyParentId]);
    20.                 $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation;
    21.             }
    Результат - Array ( [0] => 3005|5 ) Array ( [0] => 1605|6 )
    echo !!! - нет

    Да как-то яснее не стало.
     
  17. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Следовательно имеем конструкцию: if(!('3005|5')) { continue; /*ну, или echo*/ }
    Логично, что continue не выполняется? Логично.
    А теперь приведите пример данных, для которых блок в if выполняется...
     
  18. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Вообще-то в проблемном условии проверяется не $arrMetas['object_parent_relation']), а self::parseChildRelationOfParentsString($objectParentRelation).

    Тут если проверять, то так:
    PHP:
    1. foreach ($arrPosts as $keyPost => $pPost)
    2.             {
    3.                 $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru'));
    4.            
    5.                 if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null)))
    6.                     $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord;
    7.  
    8.                 if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null)))
    9.                     continue;
    10.            
    11.                     print_r(self::parseChildRelationOfParentsString($objectParentRelation));
    12.            
    13.                 if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation)))
    14.                 echo "!!!";
    15.  
    16.                 foreach ($arrObjectParentRelation as $keyParentId => $arrChildData)
    17.                     if (!in_array($keyParentId, $arrPostsIds))
    18.                         unset($arrObjectParentRelation[$keyParentId]);
    19.                 $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation;
    20.             }
    Результат - http://prntscr.com/ifmveo

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

    Хм, а как?
    Тут понимаете в чем вопрос - есть статьи у которых должны подставляться ссылки от других, но не подставляются.
    Я это дело раскуриваю и нахожу что если закомментарить continue - ссылки начинают подставляться как надо.
    При этом остальные проверки показывают что continue не должно на них срабатывать вообще, условие не выполняется.

    Т.е. ситуация, закомментарив строку, которая не должна выполняться по условию, мы решаем проблему.

    Представьте себе что этот код выводит wow только если закомментить continue;
    PHP:
    1. foreach (...){
    2. if (1 != 1) {
    3. continue;
    4. }
    5. echo "wow";
    6. }
    При этом этот код выводит wow
    PHP:
    1. foreach (...){
    2. if (1 != 1) {
    3. echo "omg";
    4. }
    5. echo "wow";
    6. }
    Но так же не бывает!
     
    #18 noindex, 16 фев 2018
    Последнее редактирование: 16 фев 2018
  19. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Перечитайте сообщение под номером 14.
    Впрочем причина всё равно одна - значение, которое приводится не к false, а к true.
    --- Добавлено ---
    Вот и проверьте, что возвращает а parseChildRelationOfParentsString($objectParentRelation)
    Можете это присваивание вынести из условия и результат его отобразить посредством var_dump(), убедившись, что возвращаемое этим методом значение не "пустое".
     
  20. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Перечитал, это моё сообщение, ничего нового с момента его написания для себя не открыл.

    Посмотрите сообщения #5 и #18.
    Там показаны результаты того что возвращает parseChildRelationOfParentsString($objectParentRelation)
    Тестовый цикл из 2-х итераций, обе итерации возвращают МАССИВ, НЕ ПУСТОЙ.
     
  21. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Что-то эта история меня начинает уже подбешивать...
    Дописал код для вывода контрольных меток:
    PHP:
    1. $i = "1";
    2. foreach ($arrPosts as $keyPost => $pPost)
    3. {
    4.     $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru'));
    5.    
    6.     if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null)))
    7.         $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord;
    8.  
    9.     if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null)))
    10.         continue;
    11.    
    12.     echo "content of iteration ".$i.": ".self::parseChildRelationOfParentsString($objectParentRelation)."<br />";
    13.  
    14.     if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation)))
    15.     continue;
    16.     echo "iteration: ".$i."<br />";
    17.    
    18.     foreach ($arrObjectParentRelation as $keyParentId => $arrChildData)
    19.         if (!in_array($keyParentId, $arrPostsIds))
    20.             unset($arrObjectParentRelation[$keyParentId]);
    21.  
    22.         $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation;
    23.  
    24.     $i++;
    25. }
    Результат:
    content of iteration 1: Array
    iteration: 1
    content of iteration 2: Array
    iteration: 2

    А теперь комменчу 2-й continue
    PHP:
    1. $i = "1";
    2. foreach ($arrPosts as $keyPost => $pPost)
    3. {
    4.     $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru'));
    5.    
    6.     if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null)))
    7.         $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord;
    8.  
    9.     if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null)))
    10.         continue;
    11.    
    12.     echo "content of iteration ".$i.": ".self::parseChildRelationOfParentsString($objectParentRelation)."<br />";
    13.  
    14.     if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation)))
    15.     //continue;
    16.     echo "iteration: ".$i."<br />";
    17.    
    18.     foreach ($arrObjectParentRelation as $keyParentId => $arrChildData)
    19.         if (!in_array($keyParentId, $arrPostsIds))
    20.             unset($arrObjectParentRelation[$keyParentId]);
    21.  
    22.         $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation;
    23.  
    24.     $i++;
    25. }
    Результат:
    content of iteration 1: Array
    content of iteration 2: Array

    WTF?!

    Получается continue не прекращает выполнение текущего цикла, а продолжает?!
    И если его нет код ниже не выполняется?!

    Чего я не понимаю?!
     
  22. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Усомнился в понимании continue, мало-ли, может слабоумие начало развиваться.
    Накидал тестовый код аналогичный проблемному, но без лишних деталей:
    PHP:
    1. $mainArray = array(0, 1);
    2. $dataArray1 = array(0=>1, 1=>1);
    3. $dataArray2 = "";
    4. function arrParser ($data){
    5.     return $data;
    6. }
    7. $i = "1";
    8. foreach ($mainArray as $key=>$value){
    9.     if (!($testVar = arrParser(${'dataArray'.$i}))){
    10.         echo "incorrect data";
    11.         continue;
    12.     }
    13.     print_r($testVar);
    14.     unset($testVar);
    15.     $i++;
    16. }
    Всё четко работает, выдает:
    Array
    (
    [0] => 1
    [1] => 1
    )
    incorrect data

    Что-то не так с этим гребанным синтаксисом...
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    фигурные скобки в первом коде расставь. Потом можно будет думать.
     
  24. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Следовательно что? Не пустой массив == true. !true === false. contiunue - в пролёте.
    Если комментируете continue, то следующий оператор (echo) не выполняется, потому что именно он... в общем, ввиду отсутствия фигурных скобок...
    --- Добавлено ---
    Приведите пример данных, которые должен вернуть метод parseChildRelationOfParentsString, чтобы сработало условие начала новой итерации...
     
  25. noindex

    noindex Новичок

    С нами с:
    31 май 2017
    Сообщения:
    16
    Симпатии:
    0
    Ну тут как я понимаю, подразумеваются границы выполнения от начала и до забора.
    Я до конца логику работы программиста написавшего это понять не могу, поэтому ограничивать границы не самый верный путь.
    Поэтому по-умолчанию считаю что работает весь кусок кода под if и foreach.

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

    Можно вместо многоточия написать что происходит?

    Как я понял из этого обсуждения, для того чтобы в НОРМАЛЬНОМ коде parseChildRelationOfParentsString ничего не должен вернуть, в этом случае должен сработать continue.
    Но тут всегда возвращается массив.