沒有任何建立在這樣的手段,但我設法通過延長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傳遞給每個路由調用也不是理想的。 –