ejunker / laravel-route-attributes
使用PHP属性自动注册路由
Requires
- php: ^8.0
- illuminate/contracts: ^10.0|^11.0
- nesbot/carbon: ^2.63|^3.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^9.5.10|^10.5
This package is auto-updated.
Last update: 2024-09-24 23:47:56 UTC
README
此包提供注解来自动注册路由。以下是一个快速示例:
use Spatie\RouteAttributes\Attributes\Get; class MyController { #[Get('my-route')] public function myMethod() { } }
此属性将自动注册此路由
Route::get('my-route', [MyController::class, 'myMethod']);
你是视觉学习者吗?
在这个视频中,你将了解PHP 8属性及其在laravel-routes-attributes内部的工作原理。
支持我们
我们投入了大量资源来创建一流的开放源代码包。您可以通过购买我们的付费产品之一来支持我们。
我们非常感谢您从您的家乡给我们寄明信片,并说明您正在使用我们的哪个包。您可以在我们的联系页面上找到我们的地址。我们将在我们的虚拟明信片墙上发布所有收到的明信片。
安装
您可以通过composer安装此包
composer require spatie/laravel-route-attributes
您可以使用以下命令发布配置文件
php artisan vendor:publish --provider="Spatie\RouteAttributes\RouteAttributesServiceProvider" --tag="config"
这是已发布配置文件的内容
return [ /* * Automatic registration of routes will only happen if this setting is `true` */ 'enabled' => true, /* * Controllers in these directories that have routing attributes * will automatically be registered. * * Optionally, you can specify group configuration by using key/values */ 'directories' => [ app_path('Http/Controllers'), app_path('Http/Controllers/Web') => [ 'middleware' => ['web'] ], app_path('Http/Controllers/Api') => [ 'prefix' => 'api', 'middleware' => 'api' ], ], ];
对于应用程序根命名空间目录之外的控制器,也可以使用目录数组中的namespace => path
模式添加。以下示例中,将包含来自Modules\Admin\Http\Controllers
的控制器。
'directories' => [ 'Modules\Admin\Http\Controllers\\' => base_path('admin-module/Http/Controllers'), // Or base_path('admin-module/Http/Controllers') => [ 'namespace' => 'Modules\Admin\Http\Controllers\\' ], app_path('Http/Controllers'), ],
用法
该包提供了一些应放在控制器类和方法上的注解。这些注解将用于自动注册路由
添加GET路由
use Spatie\RouteAttributes\Attributes\Get; class MyController { #[Get('my-route')] public function myMethod() { } }
此属性将自动注册此路由
Route::get('my-route', [MyController::class, 'myMethod']);
使用其他HTTP动词
我们没有遗漏任何HTTP动词。您可以在控制器方法上使用这些属性。
#[Spatie\RouteAttributes\Attributes\Post('my-uri')] #[Spatie\RouteAttributes\Attributes\Put('my-uri')] #[Spatie\RouteAttributes\Attributes\Patch('my-uri')] #[Spatie\RouteAttributes\Attributes\Delete('my-uri')] #[Spatie\RouteAttributes\Attributes\Options('my-uri')]
资源控制器
要注册资源控制器,请使用以下示例中的Resource
属性。
您可以使用only
或except
参数来管理您的资源路由的可用性。
您可以使用parameters
参数来修改由资源属性设置的默认参数。
您可以使用names
参数来设置资源控制器动作的路由名称。传递一个字符串值以设置每个控制器动作的基本路由名称,或传递一个数组值以定义每个控制器动作的路由名称。
您可以使用shallow
参数使嵌套资源仅应用于没有唯一子标识符的路由(index
、create
、store
)。
您可以使用apiResource
布尔参数仅包括用于API的动作。或者,您可以使用扩展Resource
属性类的ApiResource
属性,但参数apiResource
已设置为true
。
使用Resource
属性与Domain
、Prefix
和Middleware
属性也是可行的。
use Spatie\RouteAttributes\Attributes\Resource; #[Prefix('api/v1')] #[Resource( resource: 'photos.comments', apiResource: true, shallow: true, parameters: ['comments' => 'comment:uuid'], names: 'api.v1.photoComments', except: ['destroy'], )] // OR #[ApiResource(resource: 'photos.comments', shallow: true, ...)] class PhotoCommentController { public function index(Photo $photo) { } public function store(Request $request, Photo $photo) { } public function show(Comment $comment) { } public function update(Request $request, Comment $comment) { } }
上述示例中的属性将自动注册以下路由
Route::get('api/v1/photos/{photo}/comments', [PhotoCommentController::class, 'index'])->name('api.v1.photoComments.index'); Route::post('api/v1/photos/{photo}/comments', [PhotoCommentController::class, 'store'])->name('api.v1.photoComments.store'); Route::get('api/v1/comments/{comment}', [PhotoCommentController::class, 'show'])->name('api.v1.photoComments.show'); Route::match(['put', 'patch'], 'api/v1/comments/{comment}', [PhotoCommentController::class, 'update'])->name('api.v1.photoComments.update');
使用多个动词
要为所有动词注册路由,您可以使用Any
属性
#[Spatie\RouteAttributes\Attributes\Any('my-uri')]
要一次性注册几个动词的路由,您可以直接使用Route
属性。
#[Spatie\RouteAttributes\Attributes\Route(['put', 'patch'], 'my-uri')]
指定路由名称
所有HTTP动词属性都接受一个名为name
的参数,该参数接受路由名称。
use Spatie\RouteAttributes\Attributes\Get; class MyController { #[Get('my-route', name: "my-route-name")] public function myMethod() { } }
此属性将自动注册此路由
Route::get('my-route', [MyController::class, 'myMethod'])->name('my-route-name');
添加中间件
所有HTTP动词属性都接受一个名为middleware
的参数,该参数接受中间件类或中间件类数组。
use Spatie\RouteAttributes\Attributes\Get; class MyController { #[Get('my-route', middleware: MyMiddleware::class)] public function myMethod() { } }
此注释将自动注册此路由
Route::get('my-route', [MyController::class, 'myMethod'])->middleware(MyMiddleware::class);
要为类的所有方法应用中间件,您可以使用Middleware
属性。您可以将此属性与对方法应用属性混合使用。
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Middleware; #[Middleware(MyMiddleware::class)] class MyController { #[Get('my-route')] public function firstMethod() { } #[Get('my-other-route', middleware: MyOtherMiddleware::class)] public function secondMethod() { } }
这些注释将自动注册这些路由
Route::get('my-route', [MyController::class, 'firstMethod'])->middleware(MyMiddleware::class); Route::get('my-other-route', [MyController::class, 'secondMethod'])->middleware([MyMiddleware::class, MyOtherMiddleware::class]);
指定前缀
您可以在类上使用Prefix
注释来为该类所有方法的路由添加前缀。
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Post; use Spatie\RouteAttributes\Attributes\Prefix; #[Prefix('my-prefix')] class MyController { #[Get('my-get-route')] public function myGetMethod() { } #[Post('my-post-route')] public function myPostMethod() { } }
这些注释将自动注册这些路由
Route::get('my-prefix/my-get-route', [MyController::class, 'myGetMethod']); Route::post('my-prefix/my-post-route', [MyController::class, 'myPostMethod']);
指定域名
您可以在类上使用Domain
注释来为该类所有方法的路由添加前缀。
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Post; use Spatie\RouteAttributes\Attributes\Domain; #[Domain('my-subdomain.localhost')] class MyController { #[Get('my-get-route')] public function myGetMethod() { } #[Post('my-post-route')] public function myPostMethod() { } }
这些注释将自动注册这些路由
Route::get('my-get-route', [MyController::class, 'myGetMethod'])->domain('my-subdomain.localhost'); Route::post('my-post-route', [MyController::class, 'myPostMethod'])->domain('my-subdomain.localhost');
从配置键指定域名
可能需要从配置文件中定义域名,例如,您的子域名在开发环境中与生产环境不同。
// config/domains.php return [ 'main' => env('SITE_URL', 'example.com'), 'subdomain' => env('SUBDOMAIN_URL', 'subdomain.example.com') ];
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Post; use Spatie\RouteAttributes\Attributes\DomainFromConfig; #[DomainFromConfig('domains.main')] class MyController { #[Get('my-get-route')] public function myGetMethod() { } }
当解析时,它将从配置文件中获取domains.main
的值,并按以下方式注册路由;
Route::get('my-get-route', [MyController::class, 'myGetMethod'])->domain('example.com');
作用域绑定
在单个路由定义中隐式绑定多个Eloquent模型时,您可能希望将第二个Eloquent模型的作用域限定为必须为前一个Eloquent模型的子模型。
通过添加ScopeBindings
注释,您可以启用此行为
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\ScopeBindings; class MyController { #[Get('users/{user}/posts/{post}')] #[ScopeBindings] public function getUserPost(User $user, Post $post) { return $post; } }
这类似于手动在路由注册器上使用->scopeBindings()
方法
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post; })->scopeBindings();
您还可以在控制器上使用此注释以启用所有方法的隐式作用域绑定。
指定位置
您可以在类或方法上使用Where
注释来限制路由参数的格式。
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Post; use Spatie\RouteAttributes\Attributes\Where; use Spatie\RouteAttributes\Attributes\WhereAlphaNumeric; #[Where('my-where', '[0-9]+')] class MyController { #[Get('my-get-route/{my-where}')] public function myGetMethod() { } #[Post('my-post-route/{my-where}/{my-alpha-numeric}')] #[WhereAlphaNumeric('my-alpha-numeric')] public function myPostMethod() { } }
这些注释将自动注册这些路由
Route::get('my-get-route/{my-where}', [MyController::class, 'myGetMethod'])->where(['my-where' => '[0-9]+']); Route::post('my-post-route/{my-where}/{my-alpha-numeric}', [MyController::class, 'myPostMethod'])->where(['my-where' => '[0-9]+', 'my-alpha-numeric' => '[a-zA-Z0-9]+']);
为了方便起见,一些常用的正则表达式模式有辅助属性,允许您快速将模式约束添加到路由中。
#[WhereAlpha('alpha')] #[WhereAlphaNumeric('alpha-numeric')] #[WhereIn('in', ['value1', 'value2'])] #[WhereNumber('number')] #[WhereUlid('ulid')] #[WhereUuid('uuid')]
指定分组
您可以在类上使用Group
注释来为该类所有方法的路由创建具有不同域名和前缀的多个分组。
use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Post; use Spatie\RouteAttributes\Attributes\Domain; #[Group(domain: 'my-subdomain.localhost', prefix: 'my-prefix')] #[Group(domain: 'my-second-subdomain.localhost', prefix: 'my-second-prefix')] class MyController { #[Get('my-get-route')] public function myGetMethod() { } #[Post('my-post-route')] public function myPostMethod() { } }
这些注释将自动注册这些路由
Route::get('my-get-route', [MyController::class, 'myGetMethod'])->prefix('my-prefix')->domain('my-subdomain.localhost'); Route::post('my-post-route', [MyController::class, 'myPostMethod'])->prefix('my-prefix')->domain('my-subdomain.localhost'); Route::get('my-get-route', [MyController::class, 'myGetMethod'])->prefix('my-second-prefix')->domain('my-second-subdomain.localhost'); Route::post('my-post-route', [MyController::class, 'myPostMethod'])->prefix('my-second-prefix')->domain('my-second-subdomain.localhost');
指定默认值
您可以在类或方法上使用Defaults
注释来定义可选路由参数的默认值。
use Spatie\RouteAttributes\Attributes\Defaults; use Spatie\RouteAttributes\Attributes\Get; use Spatie\RouteAttributes\Attributes\Post; #[Defaults('param', 'controller-default')] class MyController extends Controller { #[Get('my-get-route/{param?}')] public function myGetMethod($param) { } #[Post('my-post-route/{param?}/{param2?}')] #[Defaults('param2', 'method-default')] public function myPostMethod($param, $param2) { } #[Get('my-default-route/{param?}/{param2?}/{param3?}')] #[Defaults('param2', 'method-default-first')] #[Defaults('param3', 'method-default-second')] public function myDefaultMethod($param, $param2, $param3) { } #[Get('my-override-route/{param?}')] #[Defaults('param', 'method-default')] public function myOverrideMethod($param) { } }
这些注释将自动注册这些路由
Route::get('my-get-route/{param?}', [MyController::class, 'myGetMethod'])->setDefaults(['param', 'controller-default']); Route::post('my-post-route/{param?}/{param2?}', [MyController::class, 'myPostMethod'])->setDefaults(['param', 'controller-default', 'param2' => 'method-default']); Route::get('my-default-route/{param?}/{param2?}/{param3?}', [MyController::class, 'myDefaultMethod'])->setDefaults(['param', 'controller-default', 'param2' => 'method-default-first', 'param3' => 'method-default-second']); Route::get('my-override-route/{param?}', [MyController::class, 'myOverrideMethod'])->setDefaults(['param', 'method-default']);
测试
composer test
变更日志
有关最近更改的更多信息,请参阅变更日志。
贡献
有关详细信息,请参阅贡献指南。
安全漏洞
有关如何报告安全漏洞的信息,请参阅我们的安全策略。
致谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。