在您的 Laravel 应用程序中使用路由注册器
发布于 作者 史蒂夫·麦克杜格尔
最近我发现了一种在 Laravel 应用程序中加载路由的独特方法,我想与大家分享。它允许您创建路由注册器类,并在其中注册您的路由。我在 Ollie Read 开发的一个软件包中看到了这一点,它引起了我的注意,因为它是一种干净且令人兴奋的路由注册方式。
您对标准 Laravel 应用程序所做的更改相对简单。我们对路由服务提供商进行了一些更改,并删除了 web 和 API 路由文件。我们首先创建一个新特性/关注点,可以添加到我们的 app/Providers/RouteServiceProvider
中,名为 MapRouteRegistrars
。将以下代码添加到这个新的特性/关注点中。
declare(strict_types=1); namespace App\Routing\Concerns; use App\Routing\Contracts\RouteRegistrar;use Illuminate\Contracts\Routing\Registrar;use RuntimeException; trait MapRouteRegistrars{ protected function mapRoutes(Registrar $router, array $registrars): void { foreach ($registrars as $registrar) { if (! class_exists($registrar) || ! is_subclass_of($registrar, RouteRegistrar::class)) { throw new RuntimeException(sprintf( 'Cannot map routes \'%s\', it is not a valid routes class', $registrar )); } (new $registrar)->map($router); } }}
如您所见,我们还需要创建一个接口/契约以供使用,并确保我们所有的注册器都实现了它。在 app/Routing/Contracts/RouteRegistrar
下创建此接口,并添加以下代码。
declare(strict_types=1); namespace App\Routing\Contracts; use Illuminate\Contracts\Routing\Registrar; interface RouteRegistrar{ public function map(Registrar $registrar): void;}
现在我们已经有了特性和接口,我们可以看看我们需要对默认路由服务提供商进行的更改。
declare(strict_types=1); namespace App\Providers; use App\Routing\Concerns\MapsRouteRegistrars;use Illuminate\Contracts\Routing\Registrar;use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; class RouteServiceProvider extends ServiceProvider{ use MapsRouteRegistrars; protected array $registrars = []; public function boot(): void { $this->routes(function (Registrar $router) { $this->mapRoutes($router, $this->registrars); }); }}
从上面的代码中,您可以看到我们在路由服务提供商中添加了一个新属性。此属性用于在 boot 方法中注册和加载应用程序的路由注册器。
现在我们已经准备好使用路由注册器来代替路由文件,让我们为我们的应用程序创建一个默认的路由注册器。这种方法在领域驱动设计或模块化系统中非常有效 - 允许每个领域或模块注册其路由。在本例中,我们将保持简单,以便您可以理解这种方法。在 app/Routing/Registrars/DefaultRegistrar.php
中创建一个新的路由注册器,并添加以下代码。
declare(strict_types=1); namespace App\Routing\Registrars; use App\Routing\Contracts\RouteRegistrar; class DefaultRegistrar implements RouteRegistrar{ public function map(Registrar $registrar): void { $registrar->view('/', 'welcome'); }}
现在我们的默认注册器已经创建,我们可以在我们的路由服务提供商中注册它,确保它被加载。
declare(strict_types=1); namespace App\Providers; use App\Routing\Concerns\MapsRouteRegistrars;use App\Routing\Registrars\DefaultRegistrar;use Illuminate\Contracts\Routing\Registrar;use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; class RouteServiceProvider extends ServiceProvider{ use MapsRouteRegistrars; protected array $registrars = [ DefaultRegistrar::class, ]; public function boot(): void { $this->routes(function (Registrar $router) { $this->mapRoutes($router, $this->registrars); }); }}
现在,如果您访问 /
,您将加载 welcome
视图,这意味着一切都已正确连接。我可以想象在我的应用程序中使用它的一个好方法,其中我有静态营销路由、博客路由、管理员路由等等。例如,我可能会想象路由服务提供商看起来像这样
declare(strict_types=1); namespace App\Providers; use App\Routing\Concerns\MapsRouteRegistrars;use App\Routing\Registrars\AdminRegistrar;use App\Routing\Registrars\BlogRegistrar;use App\Routing\Registrars\MarketingRegistrar;use Illuminate\Contracts\Routing\Registrar;use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; class RouteServiceProvider extends ServiceProvider{ use MapsRouteRegistrars; protected array $registrars = [ MarketingRegistrar::class, // Marketing Routes BlogRegistrar::class, // Blog Routes AdminRegistrar::class, // Admin Routes ]; public function boot(): void { $this->routes(function (Registrar $router) { $this->mapRoutes($router, $this->registrars); }); }}
像这样拆分路由是将标准 PHP 路由文件迁移到基于类的路由系统的好方法,这样可以更好地封装您的应用程序或领域。
您还发现了哪些其他方法来帮助您管理不断增长的应用程序?尤其是从路由的角度来看,它们一段时间后会变得有点难以控制。请在 Twitter 上告诉我们。