Laravel:如何设置全局可用的默认路由参数

Vus*_*sys 6 php laravel

我正在尝试设置一些默认路由参数,无论上下文如何,它们都将在我的应用程序中全局运行。在用于生成URL文档中,给出的示例使用的是中间件,该中间件对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',
        ]);
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不适用于HTTP请求:

Route::get('test', function (\Illuminate\Routing\UrlGenerator $urlGenerator) {
    dump($urlGenerator->getDefaultParameters());
});
Run Code Online (Sandbox Code Playgroud)

产出 []

我相信这是因为在中UrlGeneratorsetRequest方法无条件地将routeGenerator属性设置为null。在引导过程中会调用我的服务提供者的引导方法,但随后设置请求将破坏我的默认设置。

//Illuminate/Routing/UrlGenerator.php

    public function setRequest(Request $request)
    {
        $this->request = $request;

        $this->cachedRoot = null;
        $this->cachedSchema = null;
        $this->routeGenerator = null;
    }
Run Code Online (Sandbox Code Playgroud)

转储UrlGenerator期间boot,然后再转储到我的路线文件中,可以证明这一点:

网址生成器

如您所见,UrlGenerator实例两次相同,但是RouteUrlGeneratoron routeGenerator属性已更改。

我不确定设置这些默认值的更好方法。

Vus*_*sys 6

不知道为什么将在一年后引起关注,但我最终还是自己找到了解决方案。

为了向最初的问题添加更多信息,其目的是使我们能够为实时和沙箱应用程序提供相同的代码实例。要使此工作正常进行,还涉及更多的工作,但是这个问题只是有关为视图中的链接生成URL的问题。生成的所有链接始终都是子域和tld,因此此代码始终注入这些值。

这些视图不仅作为对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());
    }
}
Run Code Online (Sandbox Code Playgroud)

由于没有路由继续引起我最初询问的问题,因此这是可行的。

对于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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'),
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)