За последние 24 часа нас посетили 121452 программиста и 8074 робота. Сейчас ищут 1252 программиста ...

Запись и вывод ингредиентов (БД)

Тема в разделе "PHP для новичков", создана пользователем Assassin-3009, 24 май 2016.

  1. Assassin-3009

    Assassin-3009 Активный пользователь

    С нами с:
    24 май 2016
    Сообщения:
    55
    Симпатии:
    0
    В бд есть список продуктов,
    0.png
    который выводится вот так:
    1.png

    На сайте есть страничка добавления своего рецепта. Выбирать ингредиенты для рецепта можно из списка продуктов, имеющихся в бд.
    Например:
    Рецепт: "Сладко-солёная вода"
    Ингредиенты: Вода, Сахар, Соль
    Я понимаю, что можно сделать 100 полей и записать на столько полей, сколько ингредиентов выбрано.
    Но если я записываю все выбранные ингредиенты в одно поле (как на картинке),
    2.png
    то как их потом так же вывести по отдельности эти id ингредиентов?
     
  2. denis01

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

    С нами с:
    9 дек 2014
    Сообщения:
    12.213
    Симпатии:
    1.711
    Адрес:
    Молдова, г.Кишинёв
    ну можно создать таблицу в которой будут ингредиенты с id, потом ещё таблицу в которой будет id ингредиента и id рецепта, сможешь по id рецепта выводить все ингредиенты, почитай книгу по mysql для начинающих, там должно быть такое
     
  3. SamyRed

    SamyRed Старожил

    С нами с:
    23 июл 2015
    Сообщения:
    1.151
    Симпатии:
    108
    Адрес:
    Украина
    ++
    Лучше сделай отдельную таблицу, в которой будешь хранить ингредиенты, добавляя их при надобности. А вообще поможет split () и implode () - почитай о них. Ещё, не уверен, но, возможно, serialize () и unserialize ().
     
    SpikePHP нравится это.
  4. SpikePHP

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

    С нами с:
    6 май 2015
    Сообщения:
    130
    Симпатии:
    23
    Тоже бы использовал функцию split, а id ингредиентов писал бы через запятую в поле Ingredients ('9,17,15')

    PHP:
    1. //допустим из запроса рецепта ты получил строку с id ингредиентов
    2. $ingredients = '9,17,15';
    3.  
    4. $arr = split(',',$ingredients);
    5.  
    6. $sql = "select * from products_table where id = ".$arr[0];
    7.  
    8. foreach ($arr as &$value) {
    9.     $sql = $sql." or id=".$value;
    10. }
    11.  
    12. echo $sql;
    получаем запрос который выводит все продукты этого рецепта:

    Код (Text):
    1. select * from products_table where id = 9 or id=9 or id=17 or id=15
     
  5. Assassin-3009

    Assassin-3009 Активный пользователь

    С нами с:
    24 май 2016
    Сообщения:
    55
    Симпатии:
    0
    Всем спасибо!
    Вот такой код получился:
    Код (Text):
    1.  
    2. $ingredients = preg_split("/[,]/", $db_recipes['ingredients']);
    3. $count = substr_count($db_recipes['ingredients'],',');
    4. for($i=0;$i<$count;$i++)
    5. {
    6. $db_products = mysqli_fetch_assoc(mysqli_query($db,"SELECT * FROM products WHERE id=".$ingredients[$i].""));
    7. echo " /*продукт*/ ";
    8. }
     
    #5 Assassin-3009, 24 май 2016
    Последнее редактирование: 24 май 2016
  6. SpikePHP

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

    С нами с:
    6 май 2015
    Сообщения:
    130
    Симпатии:
    23
    Мне кажется вызывать запрос в цикле это расточительно(точно я не знаю, но думаю, что MySQL проще обработать один большой запрос, чем кучу мелких), поэтому я предпочитаю собрать запрос заранее, и лишь один раз его выполнить.
     
    denis01 нравится это.
  7. NoMonster

    NoMonster Новичок

    С нами с:
    7 май 2016
    Сообщения:
    38
    Симпатии:
    1
    страно я сделал наборот лучше так 1 таблица рецепт, другая таблица для привязки к рецепту и узнаем рецепт и получаем 1 запрос к привязки требуемых вешей и количеств. и ответ!

    Не копируй =) Сделал через класс и хватит

    PHP:
    1. /**
    2. * @property string name
    3. * @property string icon
    4. * @property int life
    5. * @property int money
    6. * @property int level
    7. */
    8. class Recipe extends \Data
    9. {
    10.     protected function getFrom()
    11.     {
    12.         return 'recipes';
    13.     }
    14.  
    15.     protected $require = [
    16.         'items' => []
    17.     ];
    18.     protected $result = [
    19.         'items' => []
    20.     ];
    21.  
    22.     /**
    23.      * @return array
    24.      */
    25.     public function getRequireItems() {
    26.         if (!$this->require['items'] AND $this->id) {
    27.             $res = \Core::getConnection()->prepare("SELECT * FROM `recipe_require_items` WHERE `recipe_id` = ?");
    28.             $res->execute([$this->id]);
    29.  
    30.             $this->require['items'] = $res->fetchAll();
    31.         }
    32.  
    33.         return $this->require['items'];
    34.     }
    35.  
    36.     /**
    37.      * @return array
    38.      */
    39.     public function getResultItems() {
    40.         if (!$this->result['items'] AND $this->id) {
    41.             $res = \Core::getConnection()->prepare("SELECT * FROM `recipe_result_items` WHERE `recipe_id` = ?");
    42.             $res->execute([$this->id]);
    43.  
    44.             $this->result['items'] = $res->fetchAll();
    45.         }
    46.  
    47.         return $this->result['items'];
    48.     }
    49.  
    50.     /**
    51.      * @return string
    52.      */
    53.     public function getName() {
    54.         return $this->name;
    55.     }
    56. }
    Вызвал нужный рецепт $recipe = new Recipe(1) где 1 id рецепта

    а дальше $recipe->getRequireItems() получаем массив нужгный предмет то есть продукты и работай!
     
  8. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    Плохое решение, т.к. невозможно сделать выборку, в каких рецептах используется данный ингредиент.
     
    SpikePHP нравится это.
  9. SpikePHP

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

    С нами с:
    6 май 2015
    Сообщения:
    130
    Симпатии:
    23
    Действительно.
    Тогда хранить id ингредиентов так : ingredients('_9_17_15_')

    А выборку через like :
    Код (Text):
    1. SELECT * FROM `recipe` WHERE ingredients like '%_9_%'
     
  10. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    Это то же самое плохое решение. Хорошее - отдельная таблица.
     
    prst и denis01 нравится это.
  11. SamyRed

    SamyRed Старожил

    С нами с:
    23 июл 2015
    Сообщения:
    1.151
    Симпатии:
    108
    Адрес:
    Украина
    Почему нельзя?
    Выбираем нужный ингридиент и перебираем все рецепты, ищем совпадение.
     
  12. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    нельзя, используюя индексы. Без индексов операции в бд это тупо перебор всех записей, и поиск подстроки в каждой записи. Каждый раз заново. Каждую строку. Это уже не БД.
     
  13. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Точнее очень плохое.
    Не только на уровне PHP но и самого SQL, к тому же если уже используется ENUM или SET, а LIKE - так тут вообще no comments.
    А если еще и все вместе использовать, процесс не остановить... :)

    И говнокодить классами не нужно ;)
    --- Добавлено ---
    Ебаный ваш лимит. 20 минут. я писал отошел, дописал - отправил.
    Все крокодилы улетели в африку :)
     
  14. SpikePHP

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

    С нами с:
    6 май 2015
    Сообщения:
    130
    Симпатии:
    23
    Значит завести поле с перечислением id рецептов, которые используют этот ингредиент, в таблице ингредиентов?
    [​IMG]
    Так будет тру?
     
  15. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    Нет. Таблица с рецептами, таблица с ингредиентами, таблица рецепт-ингредиент. Три таблицы.
     
    prst нравится это.
  16. SpikePHP

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

    С нами с:
    6 май 2015
    Сообщения:
    130
    Симпатии:
    23
    Вот так тру?
    [​IMG]
     
    denis01 нравится это.
  17. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    да. Индексы не забудь создать. Тогда выборки будут пиу-пиу, вужь-вужь!
     
    SpikePHP нравится это.