Laravel 5.7 访问books/create路由报404 删除books.show路由后可正常访问
核心问题成因
- Laravel 路由解析遵循从上到下按注册顺序匹配、命中即终止的规则,无特殊约束前提下,动态通配符路由的匹配优先级会高于后续注册的静态路径路由。
- 当前路由配置存在匹配顺序倒置的问题:
- 上层权限分组中优先注册了带通配符的动态路由
Route::get('books/{book}', 'BooksController@show') - 静态路径路由
/books/create被放在上述通配符路由的下方分组中注册
- 上层权限分组中优先注册了带通配符的动态路由
- 当访问
/books/create路径时,路由解析器会先命中books/{book}的匹配规则,将路径中的create作为{book}参数传入show路由逻辑:即尝试查询主键值为create的Book模型,查询失败后直接抛出模型不存在的404异常,后续注册的create路由根本没有机会被匹配到。 - 删除books.show路由后,上层不存在抢匹配的通配符规则,请求可以正常路由到create方法,这一测试结果完全匹配上述冲突逻辑。
解决操作步骤
- 优先调整路由注册顺序:将所有静态明确路径的路由,全部移动到带通配符参数的动态路由之前注册,从顺序上避免通配符规则抢占静态路径的匹配权。调整后的参考配置如下:
// 先注册所有静态无通配符的路由 Route::middleware('role:adm')->group(function () { Route::get('/books/create', 'BooksController@create')->name('books.create'); Route::post('books', 'BooksController@store')->name('books.store'); Route::delete('books/{book}', 'BooksController@destroy')->name('books.destroy'); }); // 后注册带通配符参数的动态路由 Route::middleware('role:adm|user')->group(function () { Route::get('books', 'BooksController@index')->name('books.index'); Route::get('books/{book}', 'BooksController@show')->name('books.show'); Route::get('books/{book}/edit', 'BooksController@edit')->name('books.edit'); Route::put('books/{book}', 'BooksController@update')->name('books.update'); });
- 调整完成后,执行路由清除命令,避免旧的路由缓存残留影响匹配结果:
php artisan route:clear - 可选优化:为所有通配符参数添加格式约束,从规则层面彻底杜绝静态路径被通配符捕获的问题。比如给
{book}参数添加纯数字约束:
Route::get('books/{book}', 'BooksController@show')->name('books.show')->where('book', '[0-9]+');
即使后续新增books/statistics、books/trash这类非数字格式的静态路径,只要不是纯数字取值,都不会被{book}参数误匹配,不需要反复调整路由注册顺序。
内容的提问来源于stack exchange,提问作者IManAsap
相关产品推荐
相关产品推荐

