glaphire
@glaphire
PHP developer

Yii2 как сделать 301 редирект с обычного урла на ЧПУ?

Есть сайт на Yii2 на advanced шаблоне.
UPD. На сайте уже настроен ЧПУ для урлов - в .htaccess папки в корне сайта, в .htaccess папки frontend/web и в urlManager конфига, прописаны правила для всех нужных роутов.
Есть ТЗ по SEO, в котором требуется сделать 301 с урлов старого, независимого от текущего, сайта вида:
UPD. Список редиректов для SEO был предоставлен после полной разработки сайта на Yii2, поэтому никакой прямой связи между урлами старого и нового сайта нет.
/index.php?p=var
/index.php?p=open_cat&cat_id=55

На ЧПУ урлы текущего сайта вида:
/controller/action
/controller/action/alias

Мои попытки решить эту задачу через .htaccess в папке app/frontend/web:
1. Сделать обычный редирект - он не работает, страница отдает 404 ошибку:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Redirect 301 /index.php?p=open_cat&cat_id=55    http://example.com/controller/action/alias
RewriteRule . index.php

2. Сделать редирект через RewriteCond и RewriteRule:
RewriteEngine on
RewriteCond %{QUERY_STRING} p=open_cat&cat_id=55
RewriteRule ^index.php$ /controller/action/alias [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

Получается вместо ожидаемого урла:
http://example.com/controller/action/alias
такой урл, который тоже неработает:
http://example.com/path-to-file-from-server-root/app/frontend/web/index.php?r=controller/action/alias

Возможно, есть вариант решить это средствами Yii2 в контроллерах, но я не понимаю, как направить такой урл на экшн.
Экшены, на которые происходит редирект, находятся в разных контроллерах, хотелось бы найти общее решение для них.
Буду благодарна за любую подсказку в направлении решения. Спасибо!
  • Вопрос задан
  • 1665 просмотров
Решения вопроса 1
glaphire
@glaphire Автор вопроса
PHP developer
Решение:
1. Создать класс компонента, нп. RedirectComponent, унаследовать его от \yii\base\Component
2. В frontend\config\main.php прописать этот класс в компонентах и бутстрапе, пример:
<?php
$params = array_merge(
    require(__DIR__ . '/../../common/config/params.php'),
    require(__DIR__ . '/../../common/config/params-local.php'),
    require(__DIR__ . '/params.php'),
    require(__DIR__ . '/params-local.php')
);

return [
    'id' => 'app-frontend',
    'basePath' => dirname(__DIR__),
    'homeUrl' => '/',
    'bootstrap' => ['RedirectComponent','log'],
    'controllerNamespace' => 'frontend\controllers',
    'components' => [
        /* */
        'RedirectComponent' => [
            'class'=>'frontend\components\RedirectComponent',
        ],   
    ],
    'params' => $params,
];

3. В классе RedirectComponent написать метод c редиректами:
public function init()
{
      /*redirect logic*/ 
}

У меня не получилось создавать редирект через динамический контроллер и экшн, использовала редирект через header().
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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