Прошу подскажите как правильно реализовать перебор. Самому не доходит никак понять. Суть в том, что у меня скрипт должен сравнивать две картинки и говорить о том, если картинка похожая найдена. В цикле я не могу понять как правильно сделать чтобы в каждой итерации главного цикла переменная $row1['images'] была передана во вложенный цикл. и чтобы я уже мог использовать эту итерационную переменную сравнивая ссылку с внешнего цикла со всеми ссылками во вложенном цикле. PHP: <? $sql_result = $db->query( "SELECT id, images, news_id FROM " . PREFIX . "_images" ); while ($row1 = $db->get_row($sql_result)) { while ($row2 = $db->get_row($sql_result)) { if (strcmp($row1['images'], $row2['images']) !== 0) { try { //исключение, потому что imagick отказывается работать если картинки разные $image1 = new Imagick("https://site.ru/uploads/posts/" . $row1['images']); $image2 = new Imagick("https://site.ru/uploads/posts/" . $row2['images']);//$row1 $res = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR); $d = round($res[1]*1000); if ($d < 10) { //Картинки похожи, но сделаем уровень сравнения поменьше чтобы схожие картинки с сильным отличием определялись как разные print "Картинки похожи ". $row2['images'] . "<br>"; } else { echo "Картинки разные"; } } catch (Exception $e) { //Картинки совершенно разные или не удалось сравнить } } } } ?>
Не очень понял, что значит "передать $row1['images'] во вложенный цикл". цикл не функция, и $row1['images'] так же хорошо виден и во внутреннем цикле, как и в основном. Если имеется в виду не повторять сравнения, то, может подойдет такой код? Код (Text): $images_table = $db->get_results("SELECT id, images, news_id FROM " . PREFIX . "_images"); for ($i = 0, $cnt = count($images_table), $i < $cnt; $i++) { $img1 = $images_table[$i]->images; for ($j = $i + 1; $j < $cnt; $j++) { $img2 = $images_table[$j]->images; try { $image1 = new Imagick("https://site.ru/uploads/posts/" . $img1); $image2 = new Imagick("https://site.ru/uploads/posts/" . $img2); $res = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR); $d = round($res[1]*1000); print "Картинки ". $img1 .", " .$img2; if ($d < 10) { print " похожи"; } else { echo " разные"; } print "<br>"; } catch (Exception $e) { //Картинки совершенно разные или не удалось сравнить } } }
Пардон, во второй строчке кода ошибочка, надо: Код (Text): for ($i = 0, $cnt = count($images_table); $i < $cnt; $i++) { Точка с запятой вместо запятой
Всем спасибо. Тему можно закрыть. Еще бы надо добавить true в $images_table = $db->get_results("SELECT id, images, news_id FROM " . PREFIX . "_images", true);
Лучше поздно. чем никогда. --- Добавлено --- Ошибся, не на ту кнопку нажал. Хотел сказать, что прав был @MouseZver Сейчас заметил, что создаются лишние объекты. Если еще не поздно, то новое, по моему мнению улучшенное решение: Код (Text): $images_table = $db->get_results("SELECT id, images, news_id FROM " . PREFIX . "_images"); $imagick = []; for ($i = 0, $cnt = count($images_table); $i < $cnt; $i++) { $imagick[$i] = new Imagick("https://site.ru/uploads/posts/" . $images_table[$i]->images); for ($j = 0; $j < $i; $j++) { try { $res = $imagick[$i] ->compareImages($imagick[$j], Imagick::METRIC_MEANSQUAREERROR); $d = round($res[1]*1000); print "Картинки ". $images_table[$i]->images .", " .$images_table[$j]->images; if ($d < 10) { print " похожи"; } else { echo " разные"; } print "<br>"; } catch (Exception $e) { //Картинки совершенно разные или не удалось сравнить } } }