使用 urldecode 预处理 lumen 路由参数
Preprocess lumen route parameters with urldecode
我目前正在使用 lumen 框架 (5.6) 构建一个 API,此 API 可用于通过标题等请求页面。这条路线是:
Route::group(["prefix" => '/api/v1', "middleware" => ["ContentTypeJson","Paginator"]], function () {
Route::group(["prefix" => '/{databaseIdentifier}', "middleware"=>"DatabaseIdentifier"], function () {
Route::group(["prefix" => '/pages'], function () {
Route::group(["prefix" => '/{title}'], function () {
Route::get("/", "PageController@getPageByTitle");
Route::get("/parents", "SearchController@getParentalSpecies");
Route::get("/all", "PageController@getPageByTitleWithLinks");
Route::get("/overlap/{overlapProperty}", "PageController@getPagesWithOverlap");
Route::put("/", "PageController@overwritePage");
});
});
});
可以看到title
用在了多个函数和controller中,同样适用于databaseIdentifier
,在中间件中用来判断需要使用哪个数据库。
然而,所有带有 space 的 url 参数将被转换为 %20
而不是 space,这是预期的行为。但是我想将其转换回原始字符串,这可以使用 urldecode()
来完成。
但由于这适用于每个控制器和功能,我想为此使用某种预处理步骤。
我已经尝试为此使用中间件来按照建议 (使用 $request->route()->setParameter('key', $value);
)更改路由参数。
不幸的是,这在 lumen 中不起作用,因为 $request->route()
的结果是一个数组而不是 object。我试过改变这个数组,但我无法让它改变 Request
object 中的实际数组。这里没有出现错误。
简而言之:我正在寻找一种方法来 url 解码每个 URL 传递给我的控制器和函数的参数,而不用将 $param = urldecode($param);
放在任何地方。
如果您需要更多信息,请随时询问
提前谢谢你
对于同样遇到此问题的任何人,我已经找到了使用中间件的解决方案。
在中间件中,我执行以下操作:
public function handle(Request $request, Closure $next)
{
$routeParameters = $request->route(null)[2];
foreach ($routeParameters as $key=>$routeParameter) {
$routeParameters[$key] = urldecode($routeParameter);
}
$routeArray = $request->route();
$routeArray[2] = $routeParameters;
$request->setRouteResolver(function() use ($routeArray)
{
return $routeArray;
});
return $next($request);
}
此代码将解码每个路由参数并将其保存在一个数组中,然后我获取由 lumen 本身创建的整个路由数组(其中包含 url 编码参数),然后将其替换为url 参数的解码版本。这还不够,因为这不会影响 Request
对象中的路由数组。
为了应用这些更改,我更改了 routeResolver
,因此它将 return 更改的数组而不是 lumen 创建的数组。
我目前正在使用 lumen 框架 (5.6) 构建一个 API,此 API 可用于通过标题等请求页面。这条路线是:
Route::group(["prefix" => '/api/v1', "middleware" => ["ContentTypeJson","Paginator"]], function () {
Route::group(["prefix" => '/{databaseIdentifier}', "middleware"=>"DatabaseIdentifier"], function () {
Route::group(["prefix" => '/pages'], function () {
Route::group(["prefix" => '/{title}'], function () {
Route::get("/", "PageController@getPageByTitle");
Route::get("/parents", "SearchController@getParentalSpecies");
Route::get("/all", "PageController@getPageByTitleWithLinks");
Route::get("/overlap/{overlapProperty}", "PageController@getPagesWithOverlap");
Route::put("/", "PageController@overwritePage");
});
});
});
可以看到title
用在了多个函数和controller中,同样适用于databaseIdentifier
,在中间件中用来判断需要使用哪个数据库。
然而,所有带有 space 的 url 参数将被转换为 %20
而不是 space,这是预期的行为。但是我想将其转换回原始字符串,这可以使用 urldecode()
来完成。
但由于这适用于每个控制器和功能,我想为此使用某种预处理步骤。
我已经尝试为此使用中间件来按照建议 $request->route()->setParameter('key', $value);
)更改路由参数。
不幸的是,这在 lumen 中不起作用,因为 $request->route()
的结果是一个数组而不是 object。我试过改变这个数组,但我无法让它改变 Request
object 中的实际数组。这里没有出现错误。
简而言之:我正在寻找一种方法来 url 解码每个 URL 传递给我的控制器和函数的参数,而不用将 $param = urldecode($param);
放在任何地方。
如果您需要更多信息,请随时询问
提前谢谢你
对于同样遇到此问题的任何人,我已经找到了使用中间件的解决方案。
在中间件中,我执行以下操作:
public function handle(Request $request, Closure $next)
{
$routeParameters = $request->route(null)[2];
foreach ($routeParameters as $key=>$routeParameter) {
$routeParameters[$key] = urldecode($routeParameter);
}
$routeArray = $request->route();
$routeArray[2] = $routeParameters;
$request->setRouteResolver(function() use ($routeArray)
{
return $routeArray;
});
return $next($request);
}
此代码将解码每个路由参数并将其保存在一个数组中,然后我获取由 lumen 本身创建的整个路由数组(其中包含 url 编码参数),然后将其替换为url 参数的解码版本。这还不够,因为这不会影响 Request
对象中的路由数组。
为了应用这些更改,我更改了 routeResolver
,因此它将 return 更改的数组而不是 lumen 创建的数组。