我目前正在撰写管理某些文章,技术文档的工具......
每篇文章都有一个部件号,其格式始终为xxxx-xxx-xx
,其中x
是一个数字。目前,我的路由设置如下:
admin/{partnumber} (List all documentation entries)
admin/{partnumber}/new (New documentation entry)
admin/{partnumber}/edit (Edit the article itself)
admin/{partnumber}/{id} (Edit the documentation with the given id for the article)
partnumber
必须与以下正则表达式匹配:
(\d{4}-\d{3}-\d{2}|\d{9})
这是,所以我不一定要输入破折号。但是,为了让我的网址看起来更容易一些,让它们更容易理解,我想自动重定向到输入的网址,但添加破折号。
example.com/admin/123456789 => example.com/admin/1234-567-89
example.com/admin/123456789/new => example.com/admin/1234-567-89/new
...
我想我可以分别为\d{9}
创建一条路线,如下所示:
Route::get('admin/{partnumber}',
'ArticleAdminController@redirectWithDashes')
->where('partnumber', '\d{9}');
然后在该控制器的功能中执行重定向。但是,这只适用于admin/{partnumber}
,而不适用于任何其他路线。
我无法想到任何方法,除了为所有路由制作两次所有功能,一次仅用于重定向。这对我来说似乎有点冗长,并且无法成为解决方案。
我的另一个想法是为指定的路由创建中间件并重定向到路由本身,但使用不同的参数。但在我看来,这似乎不是中间件的一个很好的用例。
我错过了什么吗?这有可能吗?
答案 0 :(得分:0)
如果想要在laravel中修复此问题,我会做的是创建一个中间件,例如PartnumberMiddleware
:
<?php
namespace App\Http\Middleware;
use Closure;
class PartnumberMiddleware
{
/**
* Run the request filter.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (preg_match('/^(?<number>[\d]{18})$/', $request->input('partnumber'), $matches) {
$partnumberIn = preg_split('/^\d{4}\d{3}\d{2}\d{9}$/', $matches['number']);
$partnumberMutated = implode('-', $partnumberIn);
return redirect()->route($request->route()->getActionName(), array_merge($request->route()->parameters(), ['partnumber' => $partnumberMutated]));
}
return $next($request);
}
}
未经测试,您需要填写空白。但是,一旦您注册了中间件,这应该可行。
在partnumber中添加了变异,添加了从请求对象获取路径。