没有任何建立在这样的手段,但我设法通过延长UrlGenerator
<?php
namespace App\Services;
use Illuminate\Routing\UrlGenerator as BaseGenerator;
use Illuminate\Support\Arr;
class UrlGenerator extends BaseGenerator
{
protected $default_parameters = [];
public function setDefaultParameter($key, $value){
$this->default_parameters[$key] = $value;
}
public function removeDefaultParameter($key){
unset($this->default_parameters[$key]);
}
public function getDefaultParameter($key){
return isset($this->default_parameters[$key]) ? $this->default_parameters[$key] : null;
}
protected function replaceRouteParameters($path, array &$parameters)
{
if (count($parameters) || count($this->default_parameters)) {
$path = preg_replace_sub(
'/\{.*?\}/', $parameters, $this->replaceNamedParameters($path, $parameters)
);
}
return trim(preg_replace('/\{.*?\?\}/', '', $path), '/');
}
protected function replaceNamedParameters($path, &$parameters)
{
return preg_replace_callback('/\{(.*?)\??\}/', function ($m) use (&$parameters) {
return isset($parameters[$m[1]]) ? Arr::pull($parameters, $m[1]) : ($this->getDefaultParameter($m[1]) ?: $m[0]);
}, $path);
}
}
然后重新绑定我们的子类到服务容器
class RouteServiceProvider extends ServiceProvider
{
public function register(){
parent::register();
//bind our own UrlGenerator
$this->app['url'] = $this->app->share(function ($app) {
$routes = $app['router']->getRoutes();
$url = new UrlGenerator(
$routes, $app->rebinding(
'request', function ($app, $request) {
$app['url']->setRequest($request);
}
)
);
$url->setSessionResolver(function() {
return $this->app['session'];
});
$app->rebinding('routes', function ($app, $routes) {
$app['url']->setRoutes($routes);
});
return $url;
});
}
//...
}
,以达到预期的效果然后,我需要做的就是将默认语言环境从Locale中间件注入UrlGenerator中
public function handle($request, Closure $next, $locale = null) {
//...
$this->app['url']->setDefaultParameter('locale', $locale);
return $next($request);
}
现在,route('foo.bar')
会自动将当前语言环境绑定到路由,除非明确提供另一个语言环境。
为了规范化,URL总是应该包含locale slug(不想同时拥有/ en/foo/bar和/ foo/bar)。不得不明确地将null传递给每个路由调用也不是理想的。 –