Laravel Voyager /admin路由异常:访问后台首页报非对象属性错误
你猜的完全没错!这个问题的核心就是路由匹配优先级搞反了——你的页面路由(比如那条捕获所有{slug}的路由)排在了Voyager的/admin路由前面,导致访问/admin时,Laravel先匹配到了页面路由,试图去查找slug为admin的Page模型,结果找不到对应的记录,$page变成了null,自然就会在调用$page->image时报错。
下面给你几个靠谱的解决办法:
1. 调整路由定义顺序(最直接的方案)
Laravel的路由是按照代码中定义的顺序从上到下匹配的,所以只要把Voyager的路由注册代码放在页面路由之前,就能让/admin请求优先被Voyager接管。
比如修改routes/web.php:
// 先注册Voyager的后台路由 Route::group(['prefix' => 'admin'], function () { Voyager::routes(); }); // 再注册你的页面路由(捕获{slug}的那条) Route::get('/{slug}', [PageController::class, 'show'])->name('page.show');
修改后,访问/admin时会先匹配到Voyager的路由,不会再走到页面控制器里去查找不存在的Page记录。
2. 给页面路由添加约束(适合不想调整顺序的情况)
如果不想改动路由顺序,可以给页面路由的{slug}参数加一个正则约束,排除掉admin开头的路径,让这类请求不会被页面路由捕获。
示例代码:
Route::get('/{slug}', [PageController::class, 'show'])->name('page.show') ->where('slug', '^(?!admin).*$');
这个正则^(?!admin).*$的意思是:匹配所有不以admin开头的字符串,这样/admin和/admin/posts这类路径都会跳过页面路由,直接匹配Voyager的路由。
3. 验证路由匹配结果
修改完路由后,建议执行以下命令查看完整的路由列表,确认/admin路由的处理者是Voyager:
php artisan route:list
在输出里找到GET|HEAD /admin这条路由,确认它的Action是Voyager相关的(比如Voyager\Http\Controllers\VoyagerController@index),而不是你的页面控制器。
内容的提问来源于stack exchange,提问作者Dan

