volkovecgenei
@volkovecgenei
...

Вывод товаров по категориям учитывая вложенность, как сделать?

Категории на сайте реализованы следующей таблицей
Меню:
-id
-name
-parent_id
При создании фильтров столкнулся с проблемой: я могу вывести товары, получая из get-апроса id-категори, но только если это категория максимальной вложенности.
5c67ad31d6789284777548.jpeg
А если вложенность не максимальная, допустим на примере открыть категорию "Удилища", как сделать чтобы вывелисиь товары со всех подкатегорий этой категории?
  • Вопрос задан
  • 229 просмотров
Решения вопроса 1
Compolomus
@Compolomus Куратор тега PHP
Комполом-быдлокодер
$config = array(
    'host' => 'localhost',
    'name' => 'test',
    'user' => 'root',
    'pass' => '',
);

$pdo = new \PDO('mysql:host=' . $config['host'] . ';dbname=' . $config['name'], $config['user'], $config['pass'],
    [
        \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
        \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4'",
        \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,
    ]
);

$res = $pdo->query('select * from `products` order by `parent_id` asc');

$cats = [];
$structure = [];

while ($row = $res->fetch()) {
    $cats[$row['id']] = $row;
    $structure[$row['parent_id']][] = $row['id'];
}

class Printer
{
    private $cats = [];
    private $structure = [];

    public function __construct(array $cats, array $structure)
    {
        $this->setCats($cats);
        $this->setStructure($structure);
    }

    private function setCats(array $cats): void
    {
        $this->cats = $cats;
    }

    private function setStructure(array $structure): void
    {
        $this->structure = $structure;
    }

    protected function element(int $element): string
    {
        return '<a href="' . $this->cats[$element]['id'] . '">' . $this->cats[$element]['name'] . '</a>';
    }

    private function printElement(int $element, int $dept): string
    {
        $str = $this->element($element) . PHP_EOL;
        if (is_array($this->structure[$element]) && count($this->structure[$element]) > 0) {
            foreach ($this->structure[$element] as $id) {
                $str .= $this->print($id, $dept + 1);
            }
        }

        return $str;
    }

    private function print(int $element, int $dept = 1): string
    {
        return '<ul><li>' . $this->printElement($element, $dept) . '</li></ul>' . PHP_EOL;
    }

    private function run(): string
    {
        return $this->print(current(current($this->structure)));
    }

    public function __toString(): string
    {
        return $this->run();
    }
}

echo(new Printer($cats, $structure));

структура бд
-- phpMyAdmin SQL Dump
-- version 4.8.3
-- https://www.phpmyadmin.net/
--
-- Хост: 127.0.0.1:3306
-- Время создания: Фев 16 2019 г., 11:41
-- Версия сервера: 8.0.12
-- Версия PHP: 7.2.10

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- База данных: `test`
--

-- --------------------------------------------------------

--
-- Структура таблицы `products`
--

CREATE TABLE `products` (
  `id` int(11) NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
  `parent_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

--
-- Дамп данных таблицы `products`
--

INSERT INTO `products` (`id`, `name`, `parent_id`) VALUES
(1, 'Рыбалка', 0),
(2, 'Удилища', 1),
(4, 'Спининговые', 2),
(5, 'Морские', 2),
(6, 'Катушки', 1);

--
-- Индексы сохранённых таблиц
--

--
-- Индексы таблицы `products`
--
ALTER TABLE `products`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT для сохранённых таблиц
--

--
-- AUTO_INCREMENT для таблицы `products`
--
ALTER TABLE `products`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

5c67cd0973e35415319613.png
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы