Yii-ジェダイ!
私はいくつかの古いYiiプロジェクトに取り組んでおり、それらにいくつかの機能を追加する必要があります。Yiiは非常に論理的なフレームワークですが、理解できないことがいくつかあります。たぶん私はまだYii-wayを理解していません。それで、私は私の問題を段階的に説明します。せっかちな人のために-最後に簡単に質問します。
イントロ:人間が読める形式のURLをプロジェクトに追加したいと思います。URLは次のようになります:www.site.com/article/359
そして私はそれらを次のように見せたいです:www.site.com/article/how-to-make-pretty-urls
非常に重要:古い記事は古いもので利用可能でなければなりませんURLをフォーマットし、新しい-新しいURLに。
ステップ1:まず、config/main.phpの書き換えルールを更新しました。
'<controller:\w+>/<id:\S+>' => '<controller>/view',
そして、記事テーブルに新しいtexturl列を追加しました。したがって、新しい記事のために、ここに人間が読める形式のURLを保存します。次に、テスト用にtexturlを使用して1つの記事を更新しました。
ステップ2:アプリケーションはArticleControllerのactionViewに記事を表示するので、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を2回 実行し、ページを2回表示します。これで何ができますか?私は完全に混乱しました。問題を解決する正しい方法を選択しましたか?
簡単に言うと、アクションを実行する前にID(GET-parameter)を処理してから、IDパラメーターのみを変更して要求されたアクションを(1回!)実行できますか?