Советы PHP-разработчика

Блог содержащий короткие заметки касающиеся программирования для web.

Yii2. Написание своего правила разбора и построения url

Yii2. Написание своего правила разбора и построения url

Во всех веб-приложениях, ориентированных на СЕО, невозможно обойтись без реализации ЧПУ. Сегодня я расскажу о том как реализовать произвольный класс построения и разбора url в Yii framework 2.

Допустим у нас есть ActiveRecord-модель Page со следующими полями

  • id - идентификатор записи
  • parent_id - идентификатор родителя
  • slug - последняя часть урл
  • url - полный урл без слешей в начале и конце, который формируется как url родителя + '/' + url текущей записи
  • name - название страницы
  • content - контент страницы
  • active - страница активна?

Именно для этой модели мы и будем писать правило разбора. Для этого нам необходимо реализовать интерфейс yii\web\UrlRuleInterface - это всего два метода: createUrl и parseRequest. Метод создания урл и его разбора соответственно.

Создадим класс-заглушку с пустыми методами

class PageRule implements UrlRuleInterface {
	public function createUrl($manager, $route, $params){}
	public function parseRequest($manager, $request){}
}

И добавим его в список правил урл-менеджера конфигурации веб-приложения.

'components' => [
    'urlManager' => [
        'rules' => [
            // other rules
            [
                'class' => \app\components\PageRule::class,
            ],
            // other rules
        ],
    ],
],

Начнем с написания кода построения урл по id записи. Ниже представлен готовый код с комментариями.

public function createUrl($manager, $route, $params)
{
    if ($route !== 'page/show' || isset($params['id']) === false) { // проверяем, что это маршрут для страницы и нам передали id-записи
        return false; // return false сообщает UrlManager-у, что мы не смогли построить url и необходимо попробовать применить следующее правило
    }
    $slug = Page::find() // тут все просто. Это поиск записи в БД.
        ->select('url')
        ->where(
            [
                'id' => $params['id'],
                'active' => 1,
            ]
        )
        ->scalar();
    if ($slug !== false) { // если поиск увенчался успехом, то неободимо вернуть найденный урл
        return '/' . $slug; // слеш в начале дает знать, что это абсолютный url
    }
    return false; // мы ничего не нашли в БД :(
}

Отлично. Мы научились строить ссылки. Для этого достаточно вызвать yii\helpers\Url::toRoute(['/page/show', 'id' => 5]) и мы получим url, если в БД присутствует необходимая страница и она активна.

С парсингом url тоже нет проблем. Разберем код.

public function parseRequest($manager, $request)
{
    $url = trim($request->pathInfo, '/'); // удаляем слеши из начала и конца url
    $page = Page::find() // ищем запись по url
        ->where(
            [
                'url' => $url,
                'active' => 1,
            ]
        )
        ->one();
    if ($page !== null) { // если нашли, то передаем данные в PageController::actionShow($id). В нем будем рендерить страницу
        return ['page/show', ['id' => $page->id]];
    }
    return false; // сообщаем UrlManager, что ничего не нащли и необходимо попробовать применит следующее правило
}

Вот и все. Как видите, реализовать разбор и построение ЧПУ в Yii2 не так уж и сложно.

P.S. Хочу обратить внимание, что данный пример не учитывает никаких дополнительных GET-параметров при разборе и построении url.

  • 2016-02-07 21:49:21