【发布时间】:2012-08-05 04:53:46
【问题描述】:
绝地武士!
我正在开发一些旧的 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 列。因此,我们将在 human-readable-part-of-url 中存储新文章。然后我用 texturl 更新了一篇文章进行测试。
第 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 TWICE 并显示页面两次!我能用这个做什么?我完全糊涂了。我是否选择了正确的方法来解决我的问题?
简而言之:我可以在执行任何操作之前处理 ID(GET 参数),然后只使用修改的 ID 参数运行请求的操作(一次!)吗?
【问题讨论】:
-
你能用空白参数试试吗.. return parent::beforeAction();什么是输出?
-
@VibhaJ parent::beforeAction() 返回 404 和 parent::beforeAction($action) 返回 404