Господа, всем доброго вечера. Разбираю глюки в функционале, и наткнулся на такое условие в цикле: PHP: if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation))) continue; Я как бы не совсем уж чайник, понимаю что в $arrObjectParentRelation прописывается результат выполнения функции parseChildRelationOfParentsString. Так же понимаю что при определенном условии срабатывает continue и цикл переходит к следующей итерации. НО, я не могу понять что проверяет такое условие, т.к. привык работать с простым форматом условий %) Проблема в том что continue срабатывает тогда, когда не должен, если его закомментить, то всё начинает работать, но я боюсь что просто не понимаю всей величины замысла разработчика и просто закомментив строку, я получу баг. PHP: $arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation); print_r(arrObjectParentRelation); Возвращает массив со значениями... Что проверяется в этом условии и при каком раскладе условие срабатывает? Спасибо!
если в результате присвоения переменной результата выполнения функции в переменной окажется логически ложный результат - пропустить итерацию. (иначе - работать с этим результатом)
А что в данном случае логически ложный результат? Переменная ранее не объявляется, соответственно тип не указан или речь не о типах данных? Уверен 100% Вот код в этом же цикле: PHP: $checkResult = self::parseChildRelationOfParentsString($objectParentRelation); echo "Результат parseChildRelationOfParentsString <br /> <pre>"; print_r($checkResult); echo "</pre>"; Возвращает: http://prntscr.com/if61xd
ты мне сейчас показал совсем другой код, --- Добавлено --- PHP: $arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation); print_r(arrObjectParentRelation); ? --- Добавлено --- если объект пустой то TRUE --- Добавлено --- тоже самое if ( empty ( $arrObjectParentRelation = self:arseChildRelationOfParentsString($objectParentRelation) ) ) {}
Это азы. php трактует как ложь: false, null, 0, 0.0, [] (пустой массив), "" (пустую строку), а так же (и это сюрприз от разрабов PHP и источник трудно находимых ошибок) "0" (строку, в которой записан символ 0). Оператор присвоения возвращает присвоенное значение, что позволяет писать цепочки присвоений ($a = $b = $c = $d = 255, а также вот такие условия Это понятно всем, кто знает язык, поэтому почему бы не попользоваться возможностью?
@igordata то есть... while (false !== ($entry = readdir($handle))) в миг стало говнокодом? Охуенно, чо!
Ну так естественно, в первом сообщении код с условием, а это код над условием для проверки того что parseChildRelationOfParentsString возвращает массив. Я тоже так думал, но тогда оно не должно сработать при наличии массива в возвращаемых данных %) Ыот я и подумал что чего-то недопонимаю... Да не то слово... но что есть то есть. Ну я как бы знаю что означает '=' Вопрос из-за того что условие ведет себя аномально для моего понимания. Хм. Тут дело стало интереснее. Вот весь код цикла: PHP: foreach ($arrPosts as $keyPost => $pPost) { $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru')); if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null))) $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord; if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null))) continue; if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation))) continue; foreach ($arrObjectParentRelation as $keyParentId => $arrChildData) if (!in_array($keyParentId, $arrPostsIds)) unset($arrObjectParentRelation[$keyParentId]); $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation; } Если закомментить второй continue - код начинает работать правильно (в том месте, в которое смотрю для правки). Соответственно, делаю вывод - в какой-то итерации условие перед вторым continue не срабатывает ($objectParentRelation пустой). Беру и тупо меняю второй continue на echo "!!!"; - он не срабатывает... Т.е. !!! не выводится и логика в том месте где я смотрю работает ошибочно, т.е. аналогино наличию continue %) Может тут проблема не в логике, а в синтаксисе, который например начал иначе интерпритироваться на новой версии php? В частности отсутствие фигурных скобок в циклах и условиях...
@noindex, добавьте перед проверкой вывод значения $arrMetas['object_parent_relation'] (с предварительной проверкой на isset), а в if - тот самый echo '!!!'. Заодно и узнаете, какое не приводимое к false значение принимает $objectParentRelation.
Легко. PHP: foreach ($arrPosts as $keyPost => $pPost) { $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru')); if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null))) $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord; if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null))) continue; if (isset($arrMetas['object_parent_relation'])){ print_r($arrMetas['object_parent_relation']); } if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation))) echo "!!!"; foreach ($arrObjectParentRelation as $keyParentId => $arrChildData) if (!in_array($keyParentId, $arrPostsIds)) unset($arrObjectParentRelation[$keyParentId]); $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation; } Результат - Array ( [0] => 3005|5 ) Array ( [0] => 1605|6 ) echo !!! - нет Да как-то яснее не стало.
Следовательно имеем конструкцию: if(!('3005|5')) { continue; /*ну, или echo*/ } Логично, что continue не выполняется? Логично. А теперь приведите пример данных, для которых блок в if выполняется...
Вообще-то в проблемном условии проверяется не $arrMetas['object_parent_relation']), а self:arseChildRelationOfParentsString($objectParentRelation). Тут если проверять, то так: PHP: foreach ($arrPosts as $keyPost => $pPost) { $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru')); if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null))) $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord; if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null))) continue; print_r(self::parseChildRelationOfParentsString($objectParentRelation)); if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation))) echo "!!!"; foreach ($arrObjectParentRelation as $keyParentId => $arrChildData) if (!in_array($keyParentId, $arrPostsIds)) unset($arrObjectParentRelation[$keyParentId]); $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation; } Результат - http://prntscr.com/ifmveo Не знаю на сколько оно логично, я знаю что когда его коментарю, в нужно месте всё становится ок, из чего делаю вывод что оно выполняется. Хм, а как? Тут понимаете в чем вопрос - есть статьи у которых должны подставляться ссылки от других, но не подставляются. Я это дело раскуриваю и нахожу что если закомментарить continue - ссылки начинают подставляться как надо. При этом остальные проверки показывают что continue не должно на них срабатывать вообще, условие не выполняется. Т.е. ситуация, закомментарив строку, которая не должна выполняться по условию, мы решаем проблему. Представьте себе что этот код выводит wow только если закомментить continue; PHP: foreach (...){ if (1 != 1) { continue; } echo "wow"; } При этом этот код выводит wow PHP: foreach (...){ if (1 != 1) { echo "omg"; } echo "wow"; } Но так же не бывает!
Перечитайте сообщение под номером 14. Впрочем причина всё равно одна - значение, которое приводится не к false, а к true. --- Добавлено --- Вот и проверьте, что возвращает а parseChildRelationOfParentsString($objectParentRelation) Можете это присваивание вынести из условия и результат его отобразить посредством var_dump(), убедившись, что возвращаемое этим методом значение не "пустое".
Перечитал, это моё сообщение, ничего нового с момента его написания для себя не открыл. Посмотрите сообщения #5 и #18. Там показаны результаты того что возвращает parseChildRelationOfParentsString($objectParentRelation) Тестовый цикл из 2-х итераций, обе итерации возвращают МАССИВ, НЕ ПУСТОЙ.
Что-то эта история меня начинает уже подбешивать... Дописал код для вывода контрольных меток: PHP: $i = "1"; foreach ($arrPosts as $keyPost => $pPost) { $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru')); if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null))) $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord; if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null))) continue; echo "content of iteration ".$i.": ".self::parseChildRelationOfParentsString($objectParentRelation)."<br />"; if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation))) continue; echo "iteration: ".$i."<br />"; foreach ($arrObjectParentRelation as $keyParentId => $arrChildData) if (!in_array($keyParentId, $arrPostsIds)) unset($arrObjectParentRelation[$keyParentId]); $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation; $i++; } Результат: content of iteration 1: Array iteration: 1 content of iteration 2: Array iteration: 2 А теперь комменчу 2-й continue PHP: $i = "1"; foreach ($arrPosts as $keyPost => $pPost) { $arrMetas = get_metadata('post', pll_get_post($pPost->ID, 'ru')); if (($objectPseudoRecord = (isset($arrMetas['object_pseudo_record']) ? $arrMetas['object_pseudo_record'][0] : null))) $arrPosts[$keyPost]->objectPseudoRecord = $objectPseudoRecord; if (!($objectParentRelation = (isset($arrMetas['object_parent_relation']) ? $arrMetas['object_parent_relation'][0] : null))) continue; echo "content of iteration ".$i.": ".self::parseChildRelationOfParentsString($objectParentRelation)."<br />"; if (!($arrObjectParentRelation = self::parseChildRelationOfParentsString($objectParentRelation))) //continue; echo "iteration: ".$i."<br />"; foreach ($arrObjectParentRelation as $keyParentId => $arrChildData) if (!in_array($keyParentId, $arrPostsIds)) unset($arrObjectParentRelation[$keyParentId]); $arrPosts[$keyPost]->arrObjectParentRelation = $arrObjectParentRelation; $i++; } Результат: content of iteration 1: Array content of iteration 2: Array WTF?! Получается continue не прекращает выполнение текущего цикла, а продолжает?! И если его нет код ниже не выполняется?! Чего я не понимаю?!
Усомнился в понимании continue, мало-ли, может слабоумие начало развиваться. Накидал тестовый код аналогичный проблемному, но без лишних деталей: PHP: $mainArray = array(0, 1); $dataArray1 = array(0=>1, 1=>1); $dataArray2 = ""; function arrParser ($data){ return $data; } $i = "1"; foreach ($mainArray as $key=>$value){ if (!($testVar = arrParser(${'dataArray'.$i}))){ echo "incorrect data"; continue; } print_r($testVar); unset($testVar); $i++; } Всё четко работает, выдает: Array ( [0] => 1 [1] => 1 ) incorrect data Что-то не так с этим гребанным синтаксисом...
Следовательно что? Не пустой массив == true. !true === false. contiunue - в пролёте. Если комментируете continue, то следующий оператор (echo) не выполняется, потому что именно он... в общем, ввиду отсутствия фигурных скобок... --- Добавлено --- Приведите пример данных, которые должен вернуть метод parseChildRelationOfParentsString, чтобы сработало условие начала новой итерации...
Ну тут как я понимаю, подразумеваются границы выполнения от начала и до забора. Я до конца логику работы программиста написавшего это понять не могу, поэтому ограничивать границы не самый верный путь. Поэтому по-умолчанию считаю что работает весь кусок кода под if и foreach. Если бы он был в пролете, закомментировав его результат не поменялся бы. Если я не прав, напишите чего я не понимаю. Можно вместо многоточия написать что происходит? Как я понял из этого обсуждения, для того чтобы в НОРМАЛЬНОМ коде parseChildRelationOfParentsString ничего не должен вернуть, в этом случае должен сработать continue. Но тут всегда возвращается массив.