我正在尝试设置一些默认路由参数,这些参数将在我的应用程序中全局运行,而不管上下文如何。在documentation for URL generation中,给出的示例使用的是中间件,该中间件适用于HTTP,但在非HTTP上下文中不会被调用。从CLI调用时,我也需要此功能。
我的第一个想法是让服务提供商在启动时调用defaults
方法:
<?php
namespace App\Providers;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\ServiceProvider;
class UrlDefaults extends ServiceProvider
{
public function boot(UrlGenerator $urlGenerator): void
{
$urlGenerator->defaults([
'foo' => 'abc',
'bar' => 'xyz',
]);
}
}
但这不适用于HTTP请求:
Route::get('test', function (\Illuminate\Routing\UrlGenerator $urlGenerator) {
dump($urlGenerator->getDefaultParameters());
});
输出[]
我认为这是因为在UrlGenerator
中,setRequest
方法无条件地将routeGenerator
属性设置为null
。在引导过程中会调用我的服务提供商的引导方法,但随后设置请求将破坏我的默认设置。
//Illuminate/Routing/UrlGenerator.php
public function setRequest(Request $request)
{
$this->request = $request;
$this->cachedRoot = null;
$this->cachedSchema = null;
$this->routeGenerator = null;
}
在UrlGenerator
期间转储boot
,然后在我的路由文件中再次转储可以证明这一点:
如您所见,UrlGenerator
实例两次相同,但是RouteUrlGenerator
属性上的routeGenerator
已更改。
我不确定设置这些默认值的更好方法。
答案 0 :(得分:6)
不确定将近一年后为什么会引起人们的注意,但是我最终自己找到了解决方案。
为了向原始问题添加更多信息,其目的是使我们能够为实时和沙箱应用程序提供相同的代码实例。要使此工作正常进行,还涉及更多的工作,但是这个问题只是与视图链接的URL生成有关。生成的所有链接始终都是子域和tld,因此此代码始终注入这些值。
这些视图均作为对HTTP请求(例如HTTP请求)的响应而呈现。在我们的客户区域中,也可以作为非HTTP请求的一部分,例如计划的任务,生成发票并将其通过电子邮件发送给客户。
无论如何,解决方案:
对于非HTTP上下文,服务提供商可以设置默认值:
<?php namespace App\Providers;
use App\Support\UrlDefaults;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\ServiceProvider;
class UrlDefaultsServiceProvider extends ServiceProvider
{
public function boot(UrlGenerator $urlGenerator): void
{
$urlGenerator->defaults(UrlDefaults::getDefaults());
}
}
由于没有路由引起我最初询问的问题,所以这行得通。
对于HTTP上下文,将监听RouteMatched
事件,然后注入默认值:
<?php namespace App\Listeners;
use App\Support\UrlDefaults;
use Illuminate\Routing\Router;
use Illuminate\Routing\UrlGenerator;
/**
* Class SetUrlDefaults
*
* This class listeners for the RouteMatched event, and when it fires, injects the route paramaters (subdomain, tld,
* etc) into the defaults of the UrlGenerator
*
* @package App\Listeners
*/
class SetUrlDefaults
{
private $urlGenerator;
private $router;
public function __construct(UrlGenerator $urlGenerator, Router $router)
{
$this->urlGenerator = $urlGenerator;
$this->router = $router;
}
public function handle(): void
{
$paramaters = array_merge(UrlDefaults::getDefaults(), $this->router->current()->parameters);
$this->urlGenerator->defaults($paramaters);
}
}
UrlDefaults
只是一个返回数组的简单类:
<?php namespace App\Support;
class UrlDefaults
{
public static function getDefaults(): array
{
return [
'tld' => config('app.url.tld'),
'api' => config('app.url.api'),
'foo' => config('app.url.foo'),
'bar' => config('app.url.bar'),
];
}
}
答案 1 :(得分:0)
因此,深入研究路由类的来源时,UrlGenerator类上有一个defaults()方法,但它不是单例,因此不会保留在服务提供商中设置的任何默认值。
我似乎通过在某些中间件中设置默认值来使它起作用:
Route::domain('{domain}')->middleware('route.domain')->group(function () {
//
});
namespace App\Http\Middleware;
use Illuminate\Contracts\Routing\UrlGenerator;
class SetRouteDomain
{
private $url;
public function __construct(UrlGenerator $url)
{
$this->url = $url;
}
public function handle($request, Closure $next)
{
$this->url->defaults([
'domain' => $request->getHost(),
]);
return $next($request);
}
}
答案 2 :(得分:0)
一种可能的解决方法是让路由点指向一个PHP页面,该页面具有一系列基于您传递的令牌的重定向。请参阅此Stackoverflow帖子作为示例: