我有一个我正在迁移使用Laravel的应用程序,URL可以有不同的结构,例如:
/nightowl/search/endtimefrom/3/endtimeto/7/region/EBAY-GB/catid/ALL/pagenumber/1/
而且:
/nightowl/search/endtimefrom/3/endtimeto/7/region/EBAY-GB/keyword/frogs/
两者都是有效的URL,当前的路由器是YAF框架的一部分,路由如下:
"/:tool/search/*"
它为控制器提供了一个数组,'/search/'
之后的所有内容都是键值对。
我一直在靠墙试图弄清楚如何在Laravel中完成这件事,它开始觉得这可能是不可能的!
如果不是,我该如何才能使它成为可能?!
答案 0 :(得分:2)
Laravel无法以这种方式从网址映射key => value
,因此您有几个选择。
1)修改您的应用,以便创建网址 /夜鹰/搜索endtimefrom = 3&安培; endtimeto = 7和;区域= EBAY-GB&安培; CATID = ALL&安培;页面编号= 1
2)在laravel有机会映射路线之前自己解析路线。 具体来说,我指的是劫持当前请求,解析出url,将其重写为上述格式,然后替换Laravel中的当前请求实例。
3)在控制器中执行(可能是最简单的)
使用Route::get('{tool}/search/{params?}', 'SearchController@doSearch')
然后您可以在其中解析您的控制器
class SearchController extends BaseController {
public function doSearch($tool, $params = '')
{
$params = explode('/', $params);
$mappedParams = [];
for($i = 0; $i < count($params); $i+2){
$mappedParams[$params[$i]] = $params[$i+1];
}
//$params should now contain a key/value map
}
}
所以这条路线是nightowl / search / endtimefrom / 3 / endtimeto / 7 / region / EBAY-GB / keyword / frogs
在您的控制器中,您可以使用
$tool: nightowl
$mappedParams: Array
(
endtimefrom => 3
endtimeto => 7
region => EBAY-GB
keyword => frogs
)
使用此路线nightowl / search / endtimefrom / 3 / endtimeto / 7 / region / EBAY-GB / catid / ALL / pagenumber / 1
在您的控制器中,您可以使用
$tool: nightowl
$mappedParams: Array
(
endtimefrom => 3
endtimeto => 7
region => EBAY-GB
catid => ALL
pagenumber => 1
)
答案 1 :(得分:1)
正如我的评论中所提到的,您使用的URL结构可能不是Laravel在查询字符串中执行自己的参数/参数的方式。例如,CakePHP格式为/controller/action/param:value/param:value/
等。
您可能需要编写自己的代码段,以将您的网址转换为Laravel可识别的格式。 Here's an example of how to do that:
$test = '/nightowl/search/endtimefrom/3/endtimeto/7/region/EBAY-GB/keyword/frogs/';
$test = trim($test, '/'); // remove first and last slashes if present
// break up URL by slashes
$bits = explode('/', $test);
// get controller and action
$controller = $bits[0];
$action = $bits[1];
// remove from array - only arguments are left
unset($bits[0], $bits[1]);
$temp = array_values($bits);
$arguments = array();
for($i = 0; $i < count($temp); $i++) {
// if it's an even number then it should be a key
if($i % 2 == 0 && isset($temp[$i + 1]))
$arguments[$temp[$i]] = $temp[$i + 1];
}
echo 'Controller: ' . $controller . PHP_EOL;
echo 'Action: ' . $action . PHP_EOL;
echo 'Arguments: ';
print_r($arguments);
然后,您可以使用这些变量构建一个新的URL,以便Laravel在内部进行解释。示例输出:
Controller: nightowl
Action: search
Arguments: Array
(
[endtimefrom] => 3
[endtimeto] => 7
[region] => EBAY-GB
[keyword] => frogs
)
快速浏览一下Laravel文档会让我觉得它没有设置为在URL的参数中使用键/值对。看一下关于SO的这个问题讨论相同的事情,而不是使用GET变量:Can I have a variable number of URI parameters or key-value pairs in Laravel 4?
答案 2 :(得分:0)
非常感谢您对@scrowler和@Hailwood的想法和建议! 我一直在怀疑Laravel不支持key =&gt; URL中的值对,但不确定我是否只是错过了一些东西!
通过了你的想法,我认为在一条路线的封闭中处理它可能会更好,就像这样,它感觉更接近它所属的地方,但我很乐意听到它的任何反馈:
Route::get('/{tool}/{action}/{arguments}', function(
$tool, $action, $argumentsString)
{
$arguments = \Utilities\UrlTools::urlToArgs($argumentsString);
$arguments['tool'] = $tool;
$app = app();
$controller = $app->make('SearchController', [$arguments]);
$action = "{$action}Action";
return $controller->$action();
})
->where('action', '(index|search|redirect)')
->where('arguments', '(.*)');
使用以下函数实际构建参数数组:
public static function urlToArgs($urlString)
{
$url = explode("/", trim($urlString,"/"));
$i = 1;
$key = '';
foreach ($url as $url_segment) {
if($i == 1) {
$key = $url_segment;
$i = 0;
}
else {
$request[$key] = $url_segment;
$i = 1;
}
}
return($request);
}