Снова возникла данная тема. Предположим, ситуация такая. Нужно реализовать SEF, с возможностью задавать прямые ссылки на любой контент (контроллер).
Итак, пока такой вариант. Есть таблица и модель для ЧПУ, где есть поле url (ну или alias - это и есть ЧПУ), а так же поля route и id. Существует правило класс в конфигурации (наследующее CBaseUrlRule), которое берет по ссылке из базы данных маршрут и идентификатор контента - и возвращает нужное.
Код: Выделить всё
lass SefRule extends CBaseUrlRule
{
public $connectionID = 'db';
public function createUrl($manager,$route,$params,$ampersand)
{
if( !isset($params['id']) ) return false;
// при создании ссылки - берем ЧПУ из базы данных, если есть
$url = Yii::app()->db->createCommand("SELECT `url` FROM {{sef}} WHERE `route`='$route' AND `id`='{$params['id']}';")->query()->read();
if( !$url ) return false;
// дописываем произвольные параметры, скажем ?page=5
unset($params['id']);
$suffix = '';
foreach ($params as $key => $value) $suffix .= "$key=$value&";
// Если есть параметры - допиливаем
if( isset($suffix[1]) )
{
rtrim($suffix, '&');
$suffix = '?' . $suffix;
}
return $url['url'] . $suffix; // Вуаля, метод вернет ЧПУ
}
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
{
// Если в ссылке есть слеши, значит это не ЧПУ, вида site.ru/прямая-ссылка, а маршрут - не дергаем базу данных
if( strpos($pathInfo, '/') !== false ) return false;
// Найдем маршрут
$sef = Yii::app()->db->createCommand("SELECT `id`,`route` FROM {{sef}} WHERE `url`='$pathInfo';")->query()->read();
if( !$sef) return false;
// Вернем маршрут
$_GET['id'] = $sef['id'];
return $sef['route'];
}
}
Собственно, примитивный вариант. Суть вопроса: хотелось бы хранить в базе не машрут идентификатор, а вообще - любую ссылку. Но ее на выходе нужно распарсить, чтобы выдернуть из нее маршрут и параметры. В случае, если ссылки не в виде пути ('urlFormat'=>'path') - проблем нет. А если в виде пути ссылки по умолчанию? Можно ли Yii попросить распарсить путь или будет рекурсия?
Плюс, сомнения вызывает производительность, если для каждой ссылки дергать базу данных. Кэш можно, конечно, заюзать. Но...
Ну, еще чуть-чуть и стану профи.