带有查询字符串的 Laravel 路由 url
Posted
技术标签:
【中文标题】带有查询字符串的 Laravel 路由 url【英文标题】:Laravel route url with query string 【发布时间】:2014-03-05 03:57:46 【问题描述】:在 laravel 4 上,我可以使用 route() 帮助器生成带有查询字符串的 url。但是在 4.1 上而不是:
$url = url('admin.events', array('lang' => 'en'));
// admineventsurl/?lang=en
我明白了:
$url = url('admin.events', array('lang' => 'en'));
// admineventsurl/en
我做了一些研究,所有生成 url 的 laravel 方法都使用这样的参数。如何生成带有查询字符串的 url?
【问题讨论】:
【参考方案1】:Laravel 的 route()
和 action()
辅助方法支持 URL 查询参数。 url()
辅助方法,不幸的是没有。
只需为路由参数提供一个包含键值的数组。例如:
route('products.index', ['manufacturer' => 'Samsung']);
// Returns 'http://localhost/products?manufacturer=Samsung'
您还可以包含路由参数(例如 ID 和模型)来伴随这些参数:
route('products.show', [$product->id, 'model' => 'T9X']);
// Returns 'http://localhost/products/1?model=T9X'
基本上,数组中包含字符串键的任何元素都将被视为查询参数(/products?param=value
)。任何带有整数键的内容都将被视为 URL 参数 (/products/arg
)。
动作方法也支持这一点:
action('ProductController@index', ['manufacturer' => 'Samsung']);
您还可以在 link_to_route()
和 link_to_action()
方法中提供查询参数:
link_to_route('products.index', 'Products by Samsung', ['model' => 'Samsung');
link_to_action('ProductController@index', 'Products by Samsung', ['model' => 'Samsung']);
2019 - 编辑:
如果您不能使用route()
或action()
,您可以使用Arr::query()
帮助器生成带有查询参数的URL:
url('/products?').\Illuminate\Support\Arr::query(['manufacturer' => 'Samsung']);
// Returns 'http://localhost/products?manufacturer=Samsung'
或者:
url('/products?').http_build_query(['manufacturer' => 'Samsung'], null, '&', php_QUERY_RFC3986);
// Returns 'http://localhost/products?manufacturer=Samsung'
或者创建一个简单的辅助函数:
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
function url_query($to, array $params = [], array $additional = [])
return Str::finish(url($to, $additional), '?') . Arr::query($params);
然后调用它:
url_query('products', ['manufacturer' => 'Samsung']);
// Returns 'http://localhost/products?manufacturer=Samsung'
url_query('products', ['manufacturer' => 'Samsung'], [$product->id]);
// Returns 'http://localhost/products/1?manufacturer=Samsung'
【讨论】:
感谢您的回答。我真的很喜欢它,但由于你的问题并没有真正回答我的问题,我很感激。 我不同意 - url 路径应该包含 only 特定资源的参数,并且查询字符串参数可用于以某种非必要方式修改该请求。可以说以不同语言呈现的页面是完全不同的资源,而不是修改后的版本,但我不会接受。不管 SEO 技巧如何,语义是构建应用程序最重要的部分,这让我觉得这是一种非语义方法。【参考方案2】:旁注。
我不同意@Steve Bauman 的想法(在他的回答中),即很少需要查询字符串 url,并认为 Laravel 至少应该考虑添加查询字符串功能(返回)。有很多情况下你想要查询字符串 url 而不是比基于参数的“漂亮网址”。例如,复杂的搜索过滤器...
example.com/search/red/large/rabid/female/bunny
...可能指的是与...完全相同的啮齿动物组
example.com/search/bunny/rabid/large/female/red
...但是从任何角度来看(编程、营销分析、搜索引擎优化、用户友好性),它都有些糟糕。虽然...
example.com/search?critter=bunny&gender=female&temperament=rabid&size=large&color=red
...更长更“丑”,在这种不太罕见的情况下实际上更好。 Net:友好的 URL 对某些事情很有用,而查询字符串对另一些事情很好。
回答原问题...
我需要url()
的“查询字符串”版本——所以我复制了该函数,对其进行了修改,然后将其插入/app/start/global.php
:
/**
* Generate a querystring url for the application.
*
* Assumes that you want a URL with a querystring rather than route params
* (which is what the default url() helper does)
*
* @param string $path
* @param mixed $qs
* @param bool $secure
* @return string
*/
function qs_url($path = null, $qs = array(), $secure = null)
$url = app('url')->to($path, $secure);
if (count($qs))
foreach($qs as $key => $value)
$qs[$key] = sprintf('%s=%s',$key, urlencode($value));
$url = sprintf('%s?%s', $url, implode('&', $qs));
return $url;
例子:
$url = qs_url('sign-in', array('email'=>$user->email));
//http://example.loc/sign-in?email=chris%40foobar.com
注意:看来url()
函数是可插拔的,也就是可以替换。查看vendor/laravel/framework/src/Illuminate/Support/helpers.php
:url
函数包含在if ( ! function_exists('url'))
条件中。但是你可能不得不跳过箍来做到这一点(即让 laravel 在它的版本之前加载它。)
干杯,
克里斯
【讨论】:
@DiegoCastro 看看我下面的答案 - 它有助于以标准 Laravel 方式设置路由,但无需创建全局函数或避免使用框架。很想听听你的想法。【参考方案3】:以下是我需要做的:
我在服务提供商中处理我的所有路由,我在其中定义了以下功能:
private function registerRestfulController($prefix, $controllerClass)
Route::controller($prefix, $controllerClass, $controllerClass::getRouteNames());
getRouteNames
是我的 BaseController 上的一个静态方法,它通常会返回路由,以便 RESTful 控制器可以拥有自动命名的路由。
我遇到的问题是,这在路由本身上定义了一组通配符匹配器——为了避免这种情况,我在上面的私有函数中添加了以下内容:
foreach ($controllerClass::getRoutesNames() as $name)
$route = Route::getRoutes()->getByName($name);
$cleanUri = preg_replace('/\/\\w*\?\/', '', $route->getUri());
$route->setUri($cleanUri);
这会加载您当时注册的所有路由,并立即从 URI 中删除通配符。您可以轻松地传递要为其保留通配符的路由名称的布尔值或“白名单”,这样它就不会无意中践踏 Laravel 的默认设置。运行此程序后,它会自动开始使用查询字符串变量,我发现 far 在此实例中比路径变量更可取。
【讨论】:
【参考方案4】:一种简单的方法,特别是与 jQuery Autocomplete 一起使用,它修改控制器,检查 $request 中是否有“term”:
(控制器文件)
public function list_for_autocomplete(Request $request)
if ($request->has('term'))
return YourModel::select('column_name as value')
->where('column_name', 'like', '%' . $request->input('term') . '%')
->get()
【讨论】:
以上是关于带有查询字符串的 Laravel 路由 url的主要内容,如果未能解决你的问题,请参考以下文章