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

Laravel 5.1路由如何传递id与slug参数并生成规范URL?

解决URL带Slug时的路由匹配问题

看起来你遇到的核心问题是路由规则没有正确解析id和slug之间的分隔符,导致控制器无法获取到正确的文章ID,进而抛出“Trying to get property of non-object”错误。下面一步步帮你解决:

1. 修正路由定义

首先要确保你的路由能正确匹配/blog/{id}/{slug}的格式,同时让slug成为可选参数(毕竟你的控制器只需要ID查询数据)。假设你用的是Laravel框架,路由应该这样写:

// routes/web.php
Route::get('blog/{id}/{slug?}', 'BlogController@show')->name('blog.show');

这里的{slug?}表示slug是可选参数,不管URL里有没有slug,路由都会正确提取前面的id值。

2. 生成规范的URL

在视图里生成URL时,要利用路由名称来构建,确保id和slug被正确拼接:

// 视图文件(比如blog/index.blade.php)
<a href="{{ route('blog.show', [
    'id' => $post->id,
    'slug' => Str::slug($post->title) // 用Str::slug生成标准化的slug
]) }}">{{ $post->title }}</a>

这样生成的URL就会是你想要的http://localhost:8000/blog/27/this-is-test-post格式。

3. 优化控制器逻辑

你的控制器只需要ID来获取数据,但可以额外做些优化:

// app/Http/Controllers/BlogController.php
use Illuminate\Support\Str;
use App\Models\Post;

public function show($id, $slug = null)
{
    // 用findOrFail替代find,找不到文章时直接返回404,避免null报错
    $post = Post::findOrFail($id);

    // 可选:验证URL中的slug是否和文章标题匹配,防止用户篡改slug
    if ($slug && Str::slug($post->title) !== $slug) {
        return redirect()->route('blog.show', [
            'id' => $id,
            'slug' => Str::slug($post->title)
        ]);
    }

    return view('blog.show', compact('post'));
}

为什么之前会报错?

  • 当你配置的路由是Route::get('blog/{id}', ...)时,访问/blog/27/this-is-test-post会把27/this-is-test-post整个作为$id的值传递给控制器,用这个值去查询数据库自然找不到对应的文章,$post就会是null,视图里访问$post的属性就会抛出“Trying to get property of non-object”错误。
  • 而访问/blog/27this-is-test-post时,PHP会自动将字符串27this-is-test-post转换为整数27(因为你的ID是整数类型),所以控制器能查到正确的文章,也就不会报错——但这是不规范的写法,存在数据安全风险。

内容的提问来源于stack exchange,提问作者Brij Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:26:27