За последние 24 часа нас посетили 22486 программистов и 1057 роботов. Сейчас ищут 630 программистов ...

Перебор вложенного архива

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

  1. Stanislav Serov

    Stanislav Serov Новичок

    С нами с:
    15 янв 2020
    Сообщения:
    2
    Симпатии:
    0
    Прошу подскажите как правильно реализовать перебор. Самому не доходит никак понять. Суть в том, что у меня скрипт должен сравнивать две картинки и говорить о том, если картинка похожая найдена. В цикле я не могу понять как правильно сделать чтобы в каждой итерации главного цикла переменная $row1['images'] была передана во вложенный цикл. и чтобы я уже мог использовать эту итерационную переменную сравнивая ссылку с внешнего цикла со всеми ссылками во вложенном цикле.

    PHP:
    1. <?
    2.  
    3.     $sql_result = $db->query( "SELECT id, images, news_id FROM " . PREFIX . "_images" );
    4.  
    5.     while ($row1 = $db->get_row($sql_result))
    6.     {
    7.         while ($row2 = $db->get_row($sql_result))
    8.         {
    9.             if (strcmp($row1['images'], $row2['images']) !== 0)
    10.             {
    11.                 try { //исключение, потому что imagick отказывается работать если картинки разные
    12.                     $image1 = new Imagick("https://site.ru/uploads/posts/" . $row1['images']);
    13.                     $image2 = new Imagick("https://site.ru/uploads/posts/" . $row2['images']);//$row1
    14.                  
    15.                     $res = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
    16.                     $d = round($res[1]*1000);
    17.                  
    18.                     if ($d < 10) { //Картинки похожи, но сделаем уровень сравнения поменьше чтобы схожие картинки с сильным отличием определялись как разные
    19.                         print "Картинки похожи ". $row2['images'] . "<br>";
    20.                         } else {
    21.                         echo "Картинки разные";
    22.                     }
    23.                     } catch (Exception $e) {
    24.                     //Картинки совершенно разные или не удалось сравнить
    25.                 }
    26.             }
    27.         }
    28.     }
    29.  
    30. ?>
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.743
    Симпатии:
    1.319
    Адрес:
    Лень
    $15

    usort
     
    #2 MouseZver, 15 янв 2020
    Последнее редактирование: 15 янв 2020
  3. Vinikon

    Vinikon Активный пользователь

    С нами с:
    9 ноя 2016
    Сообщения:
    10
    Симпатии:
    1
    Не очень понял, что значит "передать $row1['images'] во вложенный цикл". цикл не функция, и $row1['images'] так же хорошо виден и во внутреннем цикле, как и в основном. Если имеется в виду не повторять сравнения, то, может подойдет такой код?
    Код (Text):
    1. $images_table = $db->get_results("SELECT id, images, news_id FROM " . PREFIX . "_images");
    2. for ($i = 0, $cnt = count($images_table), $i < $cnt; $i++) {
    3.     $img1 = $images_table[$i]->images;
    4.     for ($j = $i + 1; $j < $cnt; $j++) {
    5.         $img2 = $images_table[$j]->images;
    6.         try {
    7.                     $image1 = new Imagick("https://site.ru/uploads/posts/" . $img1);
    8.                     $image2 = new Imagick("https://site.ru/uploads/posts/" . $img2);                
    9.                     $res = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
    10.                     $d = round($res[1]*1000);
    11.                     print "Картинки ". $img1 .", " .$img2;                  
    12.                     if ($d < 10) {
    13.                         print " похожи";
    14.                     } else {
    15.                         echo " разные";
    16.                     }
    17.                     print "<br>";
    18.         } catch (Exception $e) {
    19.                     //Картинки совершенно разные или не удалось сравнить
    20.         }
    21.     }
    22. }
     
  4. Vinikon

    Vinikon Активный пользователь

    С нами с:
    9 ноя 2016
    Сообщения:
    10
    Симпатии:
    1
    Пардон, во второй строчке кода ошибочка, надо:
    Код (Text):
    1. for ($i = 0, $cnt = count($images_table); $i < $cnt; $i++) {
    Точка с запятой вместо запятой
     
  5. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.743
    Симпатии:
    1.319
    Адрес:
    Лень
    говнокодим господа
     
  6. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.820
    Симпатии:
    736
    Адрес:
    Татарстан
    Порази нас ясностью и красотой своего решения, о гуру!
     
  7. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.743
    Симпатии:
    1.319
    Адрес:
    Лень
     
  8. Stanislav Serov

    Stanislav Serov Новичок

    С нами с:
    15 янв 2020
    Сообщения:
    2
    Симпатии:
    0
    Всем спасибо. Тему можно закрыть. Еще бы надо добавить true в $images_table = $db->get_results("SELECT id, images, news_id FROM " . PREFIX . "_images", true);
     
  9. Vinikon

    Vinikon Активный пользователь

    С нами с:
    9 ноя 2016
    Сообщения:
    10
    Симпатии:
    1
    Лучше поздно. чем никогда.
    --- Добавлено ---
    Ошибся, не на ту кнопку нажал. Хотел сказать, что прав был @MouseZver
    Сейчас заметил, что создаются лишние объекты. Если еще не поздно, то новое, по моему мнению улучшенное решение:
    Код (Text):
    1. $images_table = $db->get_results("SELECT id, images, news_id FROM " . PREFIX . "_images");
    2. $imagick = [];
    3. for ($i = 0, $cnt = count($images_table); $i < $cnt; $i++) {
    4.     $imagick[$i] = new Imagick("https://site.ru/uploads/posts/" . $images_table[$i]->images);
    5.     for ($j = 0; $j < $i; $j++) {
    6.         try {
    7.             $res = $imagick[$i] ->compareImages($imagick[$j], Imagick::METRIC_MEANSQUAREERROR);
    8.             $d = round($res[1]*1000);
    9.             print "Картинки ". $images_table[$i]->images .", " .$images_table[$j]->images;                
    10.             if ($d < 10) {
    11.                 print " похожи";
    12.             } else {
    13.                 echo " разные";
    14.             }
    15.             print "<br>";
    16.         } catch (Exception $e) {
    17.                     //Картинки совершенно разные или не удалось сравнить
    18.         }
    19.     }
    20. }