Laravel 本地化与 Route Resource 参数混淆
Posted
技术标签:
【中文标题】Laravel 本地化与 Route Resource 参数混淆【英文标题】:Laravel Localisation messing with Route Resource parameter 【发布时间】:2021-01-07 22:33:59 【问题描述】:在我的第二次尝试中,我通过使用Route::group
和prefixes
在使用routeMiddleware Kernel
的URL 的第一段中的locale
为我正在开发的网站实现了多语言实现。它工作得很好,除非用parameters
检索路由Resources
。
该实现有一个小问题,因为某种原因它将parameter
变成%2Fid
(这是不正确的)并且不检索我的PublicGalleriesController
请求的资源。我不明白为什么,因为当我将鼠标悬停在生成的锚点 href
上时,我看到了正确的 url 格式。但是当我点击它时,会给出一个带有混乱 url 的 404 Not Found
消息。
web.php这是我的路由组,用一个函数封装了所有路由
Route::group([
'prefix' => 'locale',
'middleware' => 'setlocale',
], function()
// all my routes are within this route group including:
Route::resource('gallery', 'PublicGalleriesController');
Auth::routes();
Route::group(['middleware' => 'auth'], function()
...
);
);
App/Http/Middleware/Localisation.php 路由通过Kernel.php
路由的中间件
public function handle($request, Closure $next)
\App::setLocale($request->segment(1));
return $next($request);
PublicGalleriesController.php 从模型中检索图像路径并将其返回到客户端视图
public function show($id)
// Show gallery group images for given group id
$pics = null;
$path = null;
$path = GalleryGroup::find($id);
$pics = Gallery::select('imagefilename', 'group_id')->where('group_id', $id)->orderBy('id', 'asc')->get()->toArray();
return view('gallery.show', compact('pics', 'path'));
当我将鼠标悬停在index.blade
上可见的画廊组照片链接上时,它在浏览器左角显示为:localhost/en/gallery/41
。 index.blade
检索图库组主键并在循环中构建 html 锚链接:<a href=" url(app()->getLocale(), 'gallery/' . $item['id']) ">$item['descrp']</a>
当我单击此链接时,它应该通过PublicGalleriesController
运行show
函数并检索所有这些画廊组照片,但返回一个404 Not Found
,浏览器中的URL 显示localhost/en/gallery%2F41
。 %2F
我相信是一个 Url 编码的正斜杠。
php artisan route:list
显示show
资源如下:
| Domain | Method | URI | Name | Action
| Middleware |
+--------+-----------------------------------------+--------------+-----------------------
| | GET|HEAD | locale/gallery/gallery | gallery.show | App\Http\Controllers\PublicGalleriesController@show
| web,setlocale |
有人可以帮我理解为什么网址变得如此混乱吗?
Laravel 版本:5.6.39
【问题讨论】:
附注,您应该在发布问题时始终包含您使用的 Laravel 版本 【参考方案1】:url
助手的签名是:
function url($path = null, $parameters = [], $secure = null)
$parameters
是一个参数数组,而不是路径,因此它对您正在使用的 /
进行编码,因为参数是 URL 的一部分而不是路径。
您可以调整对url
的调用以获得更完整的路径或使用parameters
数组作为附加段,而不是路径:
url(app()->getLocale() .'/gallery/'. $item['id']); // 1 argument
url(app()->getLocale() .'/gallery', [$item['id']]); // 2 arguments
url(app()->getLocale(), ['gallery', $item['id']]); // 2 arguments
您也可以使用route
助手:
route('gallery.show', ['locale' => app()->getLocale(), 'gallery' => $item['id']]);
如果您不想为要使用 route
帮助器生成的所有 URL 传递 locale
,则可以调整中间件以为此参数设置默认值:
public function handle($request, Closure $next)
App::setLocale($locale = $request->route('locale'));
URL::defaults(['locale' => $locale]); // set default
return $next($request);
现在您不必传递该参数:
route('gallery.show', ['gallery' => ...]);
如果您不想将locale
参数传递给您的所有路由“动作”(控制器方法和闭包),也可以这样做。您可以在返回响应之前向该中间件添加这样的行:
$request->route()->forgetParameter('locale');
【讨论】:
很多方法可以尝试。谢谢。我按照你说的添加了参数,url看起来正确,但我仍然收到以下错误:Missing required parameters for [Route: gallery.show] [URI: locale/gallery/gallery].
这就是为什么我给你一个调整中间件以删除 locale
参数的例子,所以它不会将它传递给你的控制器操作(答案的最后一行)......因为你有默认情况下 2 个路由参数它会将 2 个参数传递给您的控制器,第一个是 locale
,因此您将 locale
值作为第一个参数...。您可能应该养成将参数命名为的习惯你的方法也匹配路由参数
您应该在调用route(..., ['locale' => ...])
时为参数使用关联数组,但如果您尝试生成到gallery.show
路由的路由,您将缺少“gallery”参数,因为您没有'不知道您正在为哪个路由生成该 URL(当前是动态的)您不能硬编码您不知道的参数...您将不得不以不同的方式进行操作,可能是通过从当前路线,合并区域设置更改并将其用作route
方法的参数...但这超出了您的问题范围
Route::getCurrentRoute()->getParameters()
给你一个小提示;-)
...也许你想让自己的助手为你调用route
并与这些参数合并......如果你有麻烦我可以为你添加一些东西到这个答案......路由器和 URLGenerator 都是“可宏的”,你可以在运行时向它们添加你自己的方法,如果你不想做一个全局的另一个可能的选择辅助函数
对不起...方法是parameters
不是getParameters
以上是关于Laravel 本地化与 Route Resource 参数混淆的主要内容,如果未能解决你的问题,请参考以下文章
Laravel - Route::resource 与 Route::controller