Йии -джедаи!
Я работаю над каким-то старым проектом Yii -и должен добавить к ним некоторые функции. Yii — довольно логичный фреймворк, но в нем есть некоторые вещи, которые я не мог понять. Возможно, я еще не разобрался с Yii -. Итак, я буду описывать свою проблему шаг -за шагом -. Для нетерпеливых -краткий вопрос в конце.
Введение:Я хочу добавить в свой проект человекочитаемые -URL-адреса.Теперь URL-адреса выглядят как:www.site.com/article/359
И я хочу, чтобы они выглядели вот так:www.site.com/article/how -–-сделать -красивые -URL-адреса
Очень важно :старые статьи должны быть доступны по URL-адресам старого формата, а новые -— по новым URL-адресам.
Шаг 1:Во-первых, я обновил правила перезаписи в config/main.php :
'/' => '/view',
. И я добавил новый столбец texturl в таблицу статей. Таким образом, мы будем хранить здесь человеческий -читаемый -часть -из -url для новых статей. Затем я обновил одну статью с texturl для тестов.
Шаг 2:Приложение показывает статьи в actionView из ArticleController , поэтому я добавил туда этот код для предварительной обработки параметра ID:
if (is_numeric($id)) {
// User try to get /article/359
$model = $this->loadModel($id); // Article::model()->findByPk($id);
if ($model->text_url !== null) {
// If article with ID=359 have text url -> redirect to /article/text-url
$this->redirect(array('view', 'id' => $model->text_url), true, 301);
}
} else {
// User try to get /article/text-url
$model = Article::model()->findByAttributes(array('text_url' => $id));
$id = ($model !== null) ? $model->id : null ;
}
А затем начните устаревший код:
$model = $this->loadModel($id); // Load article by numeric ID
// etc
Он работает отлично! Но...
Шаг 3:Но у нас много действий с параметром ID! Что мы должны сделать? Обновить все действия с этим кодом? Я думаю, это некрасиво. Я нашел метод CController ::beforeAction . Выглядит неплохо! Поэтому я объявляю beforeAction и размещаю там препроцессинг ID:
protected function beforeAction($action) {
$actionToRun = $action->getId();
$id = Yii::app()->getRequest()->getQuery('id');
if (is_numeric($id)) {
$model = $this->loadModel($id);
if ($model->text_url !== null) {
$this->redirect(array('view', 'id' => $model->text_url), true, 301);
}
} else {
$model = Article::model()->findByAttributes(array('text_url' => $id));
$id = ($model !== null) ? $model->id : null ;
}
return parent::beforeAction($action->runWithParams(array('id' => $id)));
}
Да, он работает с обоими форматами URL -, но выполняет actionView . ДВАЖДЫ и показывает страницу два раза! Что я могу сделать с этим? Я совсем запутался. Выбрал ли я правильный путь решения своей проблемы?
Кратко:Могу ли я обработать ID (GET -параметр )перед выполнением каких-либо действий, а затем выполнить запрошенное действие (один раз! )с измененным только параметром ID?