Приветствую!
После нескольких лет чтения Хабра появился интерес написать и самому небольшой очерк.
Мой текст носит, скорее, самообразовательный характер. Я был бы рад дельным замечаниям и мудрым советам, так как в компании, где я проработал 2 с небольшим месяца остался один в качестве “команды разработчиков” (и такое бывает). Тимлид ушел. Наставлять на пусть истинный, как говорится, больше некому. Вот и решил выставить на ваш суд собственную реализацию роутинга для e-commerce проекта на Yii2.
Давайте представим себе условный интернет-магазин domain.zone, который может содержать товары, категории и статические страницы с одинаковой структурой url. Например:
- domain.zone/bridgestone-blizzak-ws-60-195-55r16-91r — страница продукта;
- domain.zone/category-slug — категория;
- domain.zone/article-slug — статическая страница.
На самом деле имеется еще много всяких плюшек с такой же структурой url, но давайте остановимся на этих как основных.
Начнем, пожалуй, с товаров. Опустим тонкости генерации замечатального url-alias'a «bridgestone-blizzak-ws-60-195-55r16-91r». Предположим, вся строка хранится в поле «slug» в таблице/документе товаров. Было решено явно проверять, что это именно «слуг» продукта, а не, скажем, статическая страница. Мучить БД многочисленными запросами — явно плохая идея. Поэтому использовал индекс elasticsearch. Почему не sphinx и т.п. — это тема отдельной статьи. Не будем останавливаться на выборе технологии здесь.
Итак, было создано соответствующее правило ProductUrlRule. Реализация примерно следующая:
public function parseRequest($manager, $request)
{
$slug = $request->getPathInfo();
if (!$slug) {
return false;
}
if (strpos($slug, "/")) {
return false;
}
$queryBuilder = (new frontendcomponentsElasticQueryBuilder())
->setIndex('indexName')
->setType('indexType')
->setQueryStringQuery('slug', $slug, 'and');
$loader = (new frontendcomponentsDataLoader($queryBuilder))->load();
if ($loader->getTotal() === 0) {
return false;
}
return [$this->route, ['slug' => $slug]];
}
По такому же принципу добавлены правила для категорий и статических страниц.
Такой путь показался мне самым оптимальным. Хотелось бы, конечно, обойтись исключительно правилами роутинга, без дополнительных запросов, пускай даже к индексу, но этого добиться я так и не смог.
Буду благодарен за полезные советы.