ЧПУ в Yii

23 ноября, 2015
Метки: ,

ЧПУ (человеко-понятные-урлы) — важная часть SEO оптимизации. Я не спец по SEO поэтому рассуждения о том, работает это или нет в текущих алгоритмах ранжирования оставлю специалистам. Мы же поговорим о том, как работать с SEO-ссылками в Yii2.

Настройка ЧПУ в Yii

За маршрутизацию в Yii отвечает компонент urlManager, который получает HTTP запрос и перенаправляет управление в нужный action нужного контроллера. Прелесть ситуации в том, что благодаря этому компоненту вы можете поменять схему url-ов приложения поменяв только конфигурацию urlManager-а и ничего не меняя в коде самого приложения.

    Для настройки ЧПУ нужно:

  • Убедиться, что в корне сайта есть файлик .htaccess
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php [L]
    

    и модуль mod_rewrite активен в вашей конфигурации Apache, т.е все запросы должны перенаправляться на index.php

  • Настроить urlManager.
    'urlManager' => [
                'enablePrettyUrl' => true, // использовать ЧПУ
                'showScriptName' => false, // убирает имя файла (index.php) из url
                'suffix' => '/', // все url будут заканчиваться на "/", url без / будут выдавать 404 ,
                'enableStrictParsing' => true // url должен строго соответствовать правилам, иначе 404
            ]
    
  • Прописать правила марштрутизации
    'urlManager' => [
       'enablePrettyUrl' => true,
       'enableStrictParsing' => true,
       'showScriptName' => false,
       'rules' => [
           '/' => 'site/index',
           '<controller:\w+>/' => '<controller>/index',
           '<controller:\w+>/<action:(\w|-)+>/<id:\d+>' => '<controller>/<action>',
           '<module:\w+>/<controller:\w+>/<action:(\w|-)+>' => '<module>/<controller>/<action>',
           '<controller:\w+>/<action:(\w|-)+>' => '<controller>/<action>'
          ],
    ]
    

    Обратите внимание, правила анализируются по порядку, поэтому их порядок очень важен.

Самое важное — понять как формируются правила и на что это влияет. Попробую объяснить на примере:

‘company’ => ‘site/company’

‘company/<mission:\w+>/<type:(good|best)>/<title>’ => ‘site/company’

Оба эти правила отвечают за вызов action Company контроллера site. Но один и тот-же код генерации url в коде вернет разные ссылки для каждого из этих правил:

echo Url::to(['/site/company/', 
'mission' => 'sometexthere', 
'type' => 'best', 
'title' => 'my-title']);
//для перого правила url будет таким:
//  company?mission=sometexthere&type=best&title=my-title
// а для второго таким:
// company/sometexthere/best/my-title

и по разному будут парсится эти ссылки (ссылка второго вида не будет работать для правила первого вида и наоборот). Т.к второе правило «знает», что строка после company — это параметр mission, а первое правило ничего о параметрах не знает.

Строка вида <name> называется именованным параметром. Через двоеточие можно написать любое регулярное выражение, которому должна соответствовать строка, чтобы быть присвоенной этому параметру. К примеру \d+ — любое не нулевое кол-во цифр, \w+ любое не нулевое кол-во букв, (a|b) a или b, ^cid\d{3} начинается с cid и дальше 3 цифры и тп. Повторюсь — любое регулярное выражение.В моем примере параметр title указан без фильтра, т.е с ним совпадет любое значение.

Таким образом, меняя правила в urlManager можно менять url любых страниц не меняя имен контроллеров/action, параметров и тп.

Сложные SEO ссылки в Yii

Для большинства задач достаточно правильно прописать правила в urlManager, но иногда этого мало. Например: в проекте для идентификации компании используется id-компании. Соотвественно ссылки на страницу компании генерируются как Url::to([‘/site/company/’, ‘id’ => $company->id]); Но заказчик хочет чтобы ссылка выглядела так: город/метро/тип/название компании.

Как вариант, можно прописать правило <city>/<subway>/<type>/<title>, но тогда придется дописывать параметры везде где создается url: Url::to([‘/site/company/’, ‘id’ => $company->id, ‘city’ => ‘…’ …]); Важным моментом тут является то, что эти параметры нужны исключительно для красоты SEO-ссылки и никак не влияют на работу приложения. А если завтра нужно будет убрать один параметр и добавить еще парочку тоже для красоты? Снова искать все места где создается ссылка? В таком случаи гораздо удобнее создать свое правило маршрутизации.

use yii\base\Object;
use yii\web\UrlRuleInterface;

class SEOUrl extends Object implements UrlRuleInterface
{
    public function createUrl($manager, $route, $params){
        if($route === 'site/company'){
            if (isset($params['id'])) {
                $company = Company::findOne($params['id']);
                if(!empty($company)){
                    //получаем все нужные значения 
                    ...
                    return $city.'/'.$type.'/'.$company->title;
                }
            }
        }
        return false;  // this rule does not apply
    }

    public function parseRequest($manager, $request){
        $pathInfo = $request->getPathInfo();
        if(preg_match('%^(\w+)(?:/(\w+))(?:/(\w+))$%', $pathInfo, $matches)){
            //парсим адрес и ищем компанию, ему соответствующую 
              ... 
             $params['id'] = $company->id;
             return [
                'site/company',
                $params
             ];
         }
        return false;  // this rule does not apply
    }
}

Класс должен реализовывать UrlRuleInterface, т.е в нем должны быть два методы createUrl — с описанием правила для создания url и parseRequest для разбора url. Осталось только прописать наше новое правило в urlManager

rules' => [
             ['class' => 'app\components\SEOUrl'],
... // другие правила 
]            

Если у вас возникли проблемы с ЧПУ в yii — пишите в комментариях и я на вашем примере постараюсь объяснить то, что осталось не понятным после прочтения данной статьи.


Метки: ,

Оставить комментарий

2 комментария »

    Evgenij

    Такие правила формирования урл не слабо могут нагружать загрузку из-за большого количества запросов к БД, если на странице например есть таблица с ссылками.


    FedorT

    Большое спасибо за материал!
    Полдня потратил, чтобы понять как работает urlManager и подружиться с enableStrictParsing.


Оставить комментарий:









Копирование материалов разрешено при наличии активной ссылки на источник