За последние 24 часа нас посетили 17985 программистов и 1589 роботов. Сейчас ищут 1569 программистов ...

Выборка из базы по заданнымпараметрам

Тема в разделе "Прочие вопросы по PHP", создана пользователем rudenkov, 2 ноя 2011.

  1. rudenkov

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

    С нами с:
    9 окт 2011
    Сообщения:
    20
    Симпатии:
    0
    Адрес:
    Minsk
    Имеется каталог товаров в xml файле. Необходимо выбрать и вывести все пары товаров сумма которых равна заданому значению. Ниже код и структура xml файла. Если вводишь сумму товаров 10 и более скрипт не работает, не могу понять почему. И с фильтром на повторные пары пока придумал лишь цикл с проверкой на пары ид, но это мне кажется не самый оптимальный вариант. Плюс если с аяксом никогда не работал, сложно будет разобраться как вывести результаты без презагрузки страницы?

    PHP:
    1.  
    2. <?php
    3.     class catalog{
    4.         const DB_NAME = "test.db";
    5.         const CAT_NAME = "file.xml";
    6.                
    7.         function xml2db(){
    8.             $db = new SQLite3(self::DB_NAME);
    9.             $db->exec('CREATE TABLE catalog (id INTEGER PRIMARY KEY AUTOINCREMENT,
    10.                                             title STRING,
    11.                                             price INTEGER,
    12.                                             description STRING)');
    13.             $xml = simplexml_load_file(self::CAT_NAME);
    14.             foreach ($xml as $item) {
    15.                 $db->exec("INSERT INTO catalog (title,
    16.                                             price,
    17.                                             description)
    18.                         VALUES ('$item->title', $item->price ,'$item->description')");
    19.                  
    20.             }
    21.             $db->close();
    22.         }
    23.         function filter($data){
    24.             $db = new SQLite3(self::DB_NAME);
    25.             $i = 1;
    26.             do{
    27.                 $results = $db->query("SELECT id, title, price, description FROM catalog WHERE id=$i");
    28.                 if($row = $results->fetchArray(1) and $row["price"] < $data){
    29.                     $results = $db->query("SELECT id, title, price, description FROM catalog
    30.                                             WHERE price=($data-{$row["price"]})");
    31.                     while (($rowD = $results->fetchArray(1))){
    32.                         $array[] =  $row;
    33.                         $array[] =  $rowD;     
    34.                     }
    35.                 }
    36.                 ++$i;
    37.             }while($row = $results->fetchArray(1));
    38.             $db->close();
    39.             unlink(self::DB_NAME);
    40.             return $array;
    41.         }
    42.     }
    43. ?>
    44.  

    PHP:
    1.  
    2. <?php
    3.     include "test.php";
    4. ?>
    5. <form action="<?=$_SERVER["PHP_SELF"]?>" method="post">
    6. <input type="text" name="Data">
    7. <input type="submit" value="Go">
    8. </form>
    9. <?php
    10.     catalog::xml2db();
    11.     $a = catalog::filter($_POST["Data"]);
    12.    
    13.     $i = 1;
    14.     foreach($a as $a1){
    15.         foreach($a1 as $val){
    16.             echo "<b>$val</b> ";
    17.         }
    18.         if(fmod($i,2))
    19.             echo " ... ";
    20.         else
    21.             echo "<br>";
    22.         ++$i;
    23.     }
    24. ?>
    25.  
    HTML:
    1.  
    2. <?xml version="1.0"?>
    3. <!DOCTYPE products
    4.  
    5. [
    6. <!ELEMENT products (product)+>
    7.  <!ELEMENT product (title, price, description)?>
    8.  <!ELEMENT title (#PCDATA) >
    9.  <!ELEMENT price (#PCDATA) >
    10.  <!ELEMENT description (#PCDATA) >
    11.  ]  
    12.  
    13.  >
    14.  
    15.  <products>
    16.      <product>
    17.          <title>Phone</title>
    18.          <price>1</price>
    19.          <description>Good product</description>  
    20.      </product>
    21.      <product>
    22.          <title>Beer</title>
    23.          <price>2</price>
    24.          <description>Good product</description>  
    25.      </product>
    26.      <product>
    27.          <title>book</title>
    28.          <price>3</price>
    29.          <description>Good product</description>  
    30.      </product>
    31.      <product>
    32.          <title>pencil</title>
    33.          <price>4</price>
    34.          <description>Good product</description>  
    35.      </product>
    36.      <product>
    37.          <title>clock</title>
    38.          <price>5</price>
    39.          <description>Good product</description>  
    40.      </product>
    41.      <product>
    42.          <title>iPod</title>
    43.          <price>6</price>
    44.          <description>Good product</description>  
    45.      </product>
    46.      <product>
    47.          <title>iPad</title>
    48.          <price>7</price>
    49.          <description>Good product</description>  
    50.      </product>
    51.      <product>
    52.          <title>notebook</title>
    53.          <price>8</price>
    54.          <description>Good product</description>  
    55.      </product>
    56.  </products>
    57.  
     
  2. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Я может плохо читал но смыл 29 строки от меня ускользнул
     
  3. rudenkov

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

    С нами с:
    9 окт 2011
    Сообщения:
    20
    Симпатии:
    0
    Адрес:
    Minsk
    Разность между заданой суммой покупки и ценой текущего товара.
    PHP:
    1. $data-$row["price"]
    Выбираем из базы все записи у которых цена равна разности.

    Ну скажем есть N чисел, вводим число K. Нужно вывести все пары чисел из множества N, сумма которых равна K.
     
  4. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Дык вот я и не понял нахрена тебе эта разница.
     
  5. rudenkov

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

    С нами с:
    9 окт 2011
    Сообщения:
    20
    Симпатии:
    0
    Адрес:
    Minsk
    Значение разницы и будут те числа которые нужно вытащить из базы.

    N{1 2 3 4} K=5

    1. N.1=1, K-N1=5-1=4, SELECT... // return N4=4
    2. N.2=2, K-N2=5-2=3, SELECT...// return N3=3
    3. N.3=3, K-N3=5-3=2, SELECT...// return N2=2
    4. N.4=4, K-N4=5-4=1, SELECT...// return N1=1

    echo // N1-N4 | N2-N3 | N3-N2 | N4-N1

    Видно что 3 и 4 итерации выдадут повторы пар, которые нужно исключить.

    Обьяснил самым подробнейшим образом, если и сейчас непонятно, тему можно закрыть...
     
  6. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Если я правильно понял задачу, то, наверно, так:
    PHP:
    1. <pre>
    2. <?php
    3. $summ = 7;
    4. // В этом массиве могут быть соответствия между id товара
    5. // и его ценой (id => price), полученные из б.д.
    6. $arr1 = array(
    7.     1 => 1,
    8.     2 => 2,
    9.     3 => 3,
    10.     4 => 4,
    11.     5 => 5,
    12.     6 => 6,
    13.     7 => 7
    14. );
    15. $arr2 = $arr1;
    16. $results = array();
    17. foreach($arr1 as $id1 => $price1) {
    18.     foreach($arr2 as $id2 => $price2) {
    19.         if(($price1 + $price2 ) == $summ)
    20.             $results[] = array($id1, $id2);
    21.     }
    22.     // Мы сравнили текущий элемент массива $arr1 со всеми значениями
    23.     // массива $arr2. Массивы одинаковы. Чтобы избежать повторов, а
    24.     // также не заствалять php выполнять ненужные нам итерации цикла
    25.     // удалим соответствующий элемент из второго массива (из первого
    26.     // удаление бесполезно, так как он ещё перебирается, а вот второй
    27.     // будет перебран сначала)
    28.     reset($arr2);
    29.     unset($arr2[(key($arr2))]);
    30. }
    31. // Здесь искомые данные: каждый элемент массива $results является
    32. // массивом, который содержит два значения. Это два ID товаров,
    33. // сумма цен которых равна заданному $summ
    34. print_r($results);
    35. ?>
    36. </pre>
    Может у этой задачи есть и более изящное и правильное решение, не знаю даже. Чё-то на ум только такое сейчас пришло. Но я ещё не ложился и пол ночи пьянствовал.
     
  7. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Не понимаю ЗАЧЕМ тебе разница, а не как ее использовать в запросе.
     
  8. rudenkov

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

    С нами с:
    9 окт 2011
    Сообщения:
    20
    Симпатии:
    0
    Адрес:
    Minsk
    Решил задачу следующим образом. Еще есть необходимость вывести результат без перезагрузки страницы. Почитал в инете, понял что это делается с помощью AJAX, но с ним никогда не сталкивался, да и Javascript не знаю. Если это не сложно, может кто нибудь обьяснит как сделать, если нет полезу разбираться, время поджимает, нужно закончить как можно быстрее.

    PHP:
    1. <?php
    2.     class catalog{
    3.         const DB_NAME = "test.db";
    4.         const CAT_NAME = "file.xml";
    5.                
    6.         function xml2db(){
    7.             $db = new SQLite3(self::DB_NAME);
    8.             $db->exec('CREATE TABLE catalog (id INTEGER PRIMARY KEY AUTOINCREMENT,
    9.                                             title STRING,
    10.                                             price INTEGER,
    11.                                             description STRING)');
    12.             $xml = simplexml_load_file(self::CAT_NAME);
    13.             foreach ($xml as $item) {
    14.                 $db->exec("INSERT INTO catalog (title,
    15.                                             price,
    16.                                             description)
    17.                         VALUES ('$item->title', $item->price ,'$item->description')");
    18.                  
    19.             }
    20.             $db->close();
    21.         }
    22.        
    23.         function filter($data){
    24.             $data = strip_tags(trim($data));
    25.             $db = new SQLite3(self::DB_NAME);
    26.             $results = $db->query("SELECT catA.*, catB.* FROM catalog catA, catalog catB WHERE catA.price + catB.price = $data and catA.id < catB.id");
    27.             $i = 0;
    28.             while ($row = $results->fetchArray(2)){
    29.                 $array[] = $row;
    30.                 ++$i;
    31.             }
    32.             $db->close();
    33.             unlink(self::DB_NAME);
    34.             if($i == 0)
    35.                 return 0;
    36.             else
    37.                 return $array;
    38.         }
    39.     }
    40. ?>
    41.  

    PHP:
    1.  
    2. <?php
    3.     include "test.php";
    4. ?>
    5. <form method="POST" action="<?=$_SERVER["PHP_SELF"]?>">
    6.     Введите сумму:
    7.     <input type="text" name="Data">
    8.     <input type="submit" value="Искать">
    9. </form>
    10.  
    11. <?php
    12.     if($_SERVER["REQUEST_METHOD"]=="POST"){
    13.         catalog::xml2db();
    14.         $result = catalog::filter($_POST["Data"]);
    15.         if($result == 0)
    16.             echo "<h3>Нет подходящих товаров!</h3>";
    17.         else
    18.             foreach($result as $val)
    19.                 echo "$val[1] $val[2] $val[3] <b>AND</b> $val[5] $val[6] $val[7]<br>";         
    20.     }
    21. ?>
    22.  
     
  9. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Сделай по-классически, без аякса. Лучше хорошая реализация, чем кривая но модная. Потом переделаешь на аякс.

    А вобще см примеры jquery ajax и json.
     
  10. rudenkov

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

    С нами с:
    9 окт 2011
    Сообщения:
    20
    Симпатии:
    0
    Адрес:
    Minsk
    Вы имеете в виду инклюдить в эту область?
     
  11. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Мда =)
    Да хошь - инклудь. Не хошь - не инклудь! :D
     
  12. Kaner

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

    С нами с:
    6 янв 2011
    Сообщения:
    58
    Симпатии:
    0
    Насчет аякса: используй iframe.

    Тут все хорошо описано: http://biznesguide.ru/coding/126.html

    чуть скрипт переделаешь и все будет ок.