You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Yii2中修改URL?移除URL中的ID是否可行?

当然可以实现!

要把URL从blog/74/title-news改成blog/title-news,你需要调整两处核心内容:路由规则,以及后端获取文章的逻辑(毕竟原来靠ID定位内容,现在要换成title了)。

1. 修改路由规则

把现有的路由规则替换成不带<id>的版本:

'rules' => [
    'blog/<title>' => 'blog/details/',
]

这样当用户访问blog/title-news时,服务器会直接把请求转发到blog/details方法,同时把title-news作为title参数传递给后端。

如果需要兼容旧的URL(比如之前的blog/74/title-news还能正常访问),可以保留旧规则并新增新规则,注意新规则要放在旧规则前面(路由匹配是按顺序来的):

'rules' => [
    'blog/<title>' => 'blog/details/',
    'blog/<id>/<title>' => 'blog/details/', // 保留旧规则,兼容历史链接
]

2. 适配后端details方法的逻辑

原来的方法应该是通过id查询文章,现在要改成通过title(或者你存储的URL友好版标题,比如slug)来查询。这里有几个关键细节要注意:

  • 确保你的文章标题(或slug)是全局唯一的,不然多个文章用同一个标题会导致查询返回错误内容。
  • 如果数据库里存的是原始标题(比如带空格的),要先把URL里的短横线格式转换成匹配的格式,再去查询。

举个代码例子(假设用类似Yii的PHP框架):

原来的代码(靠ID查询):

public function actionDetails($id) {
    $post = Post::findOne($id);
    // 后续渲染逻辑...
}

修改后的代码(靠title/slug查询):

public function actionDetails($title) {
    // 把URL里的短横线转成空格,匹配原始标题;如果存的是slug,直接用$title查询
    $formattedTitle = str_replace('-', ' ', $title);
    $post = Post::findOne(['title' => $formattedTitle]);
    
    // 如果没找到文章,返回404
    if (!$post) {
        throw new NotFoundHttpException('Article not found');
    }
    
    // 后续渲染逻辑...
}

如果要兼容新旧URL,方法可以改成支持两种参数:

public function actionDetails($id = null, $title = null) {
    if ($id) {
        $post = Post::findOne($id);
    } elseif ($title) {
        $post = Post::findOne(['slug' => $title]);
    } else {
        throw new NotFoundHttpException('Article not found');
    }
    
    // 后续渲染逻辑...
}

额外提醒

在生成新URL的时候,要确保把标题转换成URL安全的slug格式(比如小写、短横线替换空格、去掉特殊字符),避免出现无效URL的问题。比如把"Title News"转换成"title-news"再生成链接。

内容的提问来源于stack exchange,提问作者Juliany Raiol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:28:46