E
E
Evgeniy V.2019-02-16 09:27:52
PHP
Evgeniy V., 2019-02-16 09:27:52

Displaying products by category considering nesting, how to do?

Categories on the site are implemented by the following
Menu table:
-id
-name
-parent_id
When creating filters, I ran into a problem: I can display products by getting the category id from the get-request, but only if this is the maximum nesting category.
5c67ad31d6789284777548.jpeg
And if the nesting is not maximum, let's use the example to open the "Rods" category, how to make it possible to display products from all subcategories of this category?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry, 2019-02-16
@volkovecgenei

$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));

database 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[email protected]@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD[email protected]@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD[email protected]@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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question