Laravel 5 - 控制器中的路由和可变参数
Laravel 5 - Routes and variable parameters in controllers
我想在搜索时生成这样的 SEO 友好 URL:
http://www.example.com/search(无过滤器)
http://**www.example.com/search/region-filter
http://**www.example.com/search/region-filter/city-filter
并以这种方式对它们进行分页:
http://www.example.com/search/2(无过滤器,第 2 页)
http://**www.example.com/search/region-filter/2
http://**www.example.com/search/region-filter/city-filter/2
(抱歉我不能 post 超过 2 个链接因为声誉)
因此第二段可以是一个过滤器或多个页面(与第三段相同)。
我的Laravel 5路由文件:
Route::pattern('page', '[0-9]+');
...
Route::get('search/{region}/{city}/{page?}', 'SearchController@index');
Route::get('search/{region}/{page?}', 'SearchController@index');
Route::get('search/{page?}', 'SearchController@index');
由于 'page' 模式,路由工作正常,但在控制器内部,此请愿书 http://**www.example.com/search/2 将 {page} 映射到 $region(甚至使用最后的路由规则):
public function index($region='', $city='', $page='')
Codeigniter 参数按名称映射,但看起来 Laravel 按位置映射它们,所以我总是在 $region 中获得第一个。
是否可以按名称而不是位置来路由参数,或者使用一些 Laravel 替代方法将它们放入控制器?(我可以计算段数,但它对我来说是一个丑陋的解决方案)
您可以使用Route::current()
方法访问当前路由,并通过parameter method
方法按名称获取参数。但是你的路由定义有问题,这会使最后定义的两条路由无用。
因为最后两条路由中的 page
参数是可选的,根据路由路径,您的第二条和第三条路由将无法正确匹配,因为路由定义不明确。下面你有证明我观点的测试用例。
如果你的控制器中有这个:
public function index()
{
$route = \Route::current();
$region = $route->parameter('region');
$city = $route->parameter('city');
$page = $route->parameter('page');
$params = [
'region' => $region,
'city' => $city,
'page' => $page
];
return $params;
}
您将获得每条路线的以下结果:
1. 对于 example.com/search/myregion/mycity/mypage
:
{
"region": "myregion",
"city": "mycity",
"page": "mypage"
}
2. 对于 example.com/search/myregion/mypage
:
{
"region": "myregion",
"city": "mypage",
"page": null
}
3. 对于 example.com/search/mypage
:
{
"region": "mypage",
"city": null,
"page": null
}
所以你的问题不是按顺序或按名称匹配参数,而是路由定义。要解决此问题,您可以只在查询字符串中添加分页并将其完全删除路由定义,因为如果分页是可选的,将分页作为查询字符串参数绝对没有错。所以你的 URL 看起来像这样:
example.com/search/myregion/mycity?page=2
您可以查看 Illuminate\Routing\Route class API 以查看您还有哪些其他可用方法。
我想在搜索时生成这样的 SEO 友好 URL:
http://www.example.com/search(无过滤器)
http://**www.example.com/search/region-filter
http://**www.example.com/search/region-filter/city-filter
并以这种方式对它们进行分页:
http://www.example.com/search/2(无过滤器,第 2 页)
http://**www.example.com/search/region-filter/2
http://**www.example.com/search/region-filter/city-filter/2
(抱歉我不能 post 超过 2 个链接因为声誉)
因此第二段可以是一个过滤器或多个页面(与第三段相同)。
我的Laravel 5路由文件:
Route::pattern('page', '[0-9]+');
...
Route::get('search/{region}/{city}/{page?}', 'SearchController@index');
Route::get('search/{region}/{page?}', 'SearchController@index');
Route::get('search/{page?}', 'SearchController@index');
由于 'page' 模式,路由工作正常,但在控制器内部,此请愿书 http://**www.example.com/search/2 将 {page} 映射到 $region(甚至使用最后的路由规则):
public function index($region='', $city='', $page='')
Codeigniter 参数按名称映射,但看起来 Laravel 按位置映射它们,所以我总是在 $region 中获得第一个。
是否可以按名称而不是位置来路由参数,或者使用一些 Laravel 替代方法将它们放入控制器?(我可以计算段数,但它对我来说是一个丑陋的解决方案)
您可以使用Route::current()
方法访问当前路由,并通过parameter method
方法按名称获取参数。但是你的路由定义有问题,这会使最后定义的两条路由无用。
因为最后两条路由中的 page
参数是可选的,根据路由路径,您的第二条和第三条路由将无法正确匹配,因为路由定义不明确。下面你有证明我观点的测试用例。
如果你的控制器中有这个:
public function index()
{
$route = \Route::current();
$region = $route->parameter('region');
$city = $route->parameter('city');
$page = $route->parameter('page');
$params = [
'region' => $region,
'city' => $city,
'page' => $page
];
return $params;
}
您将获得每条路线的以下结果:
1. 对于 example.com/search/myregion/mycity/mypage
:
{
"region": "myregion",
"city": "mycity",
"page": "mypage"
}
2. 对于 example.com/search/myregion/mypage
:
{
"region": "myregion",
"city": "mypage",
"page": null
}
3. 对于 example.com/search/mypage
:
{
"region": "mypage",
"city": null,
"page": null
}
所以你的问题不是按顺序或按名称匹配参数,而是路由定义。要解决此问题,您可以只在查询字符串中添加分页并将其完全删除路由定义,因为如果分页是可选的,将分页作为查询字符串参数绝对没有错。所以你的 URL 看起来像这样:
example.com/search/myregion/mycity?page=2
您可以查看 Illuminate\Routing\Route class API 以查看您还有哪些其他可用方法。