什么是 GeneratorCommand
Illuminate\Console\GeneratorCommand 是 Laravel 中所有代码生成命令的抽象基类。make:model、make:controller、make:request 等都继承自它。
如果你的包提供了独立的 make:xxx 命令,用户就不必手动创建类文件,而只需运行 php artisan make:handler OrderHandler,即可在正确的命名空间中生成文件。
GeneratorCommand 在官方文档中几乎没有涉及,只有直接阅读框架源码才能了解。它是典型的进阶主题。最小实现
继承GeneratorCommand 的类只需实现 getStub() 方法。其他属性是可选的,但实际中通常都会一起配好。
下面是实现
make:handler 命令的示例。
getDefaultNamespace() 后,运行 php artisan make:handler OrderHandler 会在 app/Handlers/OrderHandler.php 生成 App\Handlers\OrderHandler 类。
创建 stub 文件
将 stub 文件放到getStub() 返回的路径。stub 是模板 PHP 文件,其中的占位符会被替换为命名空间与类名。
src
Console
Commands
HandlerMakeCommand.php
stubs
handler.stub
handler.stub
GeneratorCommand 会自动替换 stub 中的以下占位符。
{{ namespace }} 与 DummyNamespace 的效果相同。Laravel 内置的 stub 同时使用了两种形式,但新建时推荐使用 {{ namespace }} 形式。
让 stub 支持自定义
要为用户提供可覆盖 stub 的机制,请使用resolveStubPath() 模式。先在 Service Provider 的 boot() 中发布 stub。
getStub() 中优先使用用户自定义的 stub。
php artisan vendor:publish --tag=stubs 之后,可以编辑项目根目录下的 stubs/handler.stub 来修改模板。
注册到 Service Provider
命令在 Service Provider 的boot() 方法中注册。通过 runningInConsole() 判断,可以避免 Web 请求时不必要的加载。
composer.json 中配置 extra.laravel,用户就不必手动注册 Service Provider。
应用示例
以下列举了GeneratorCommand 大显身手的几个场景。
Form Request 扩展
Form Request 扩展
生成继承自定义基类(包含认证检查、自定义验证逻辑)的 Request 类的命令。在
getDefaultNamespace() 返回 App\Http\Requests。DTO 生成器
DTO 生成器
生成 Data Transfer Object 样板的命令。准备包含 readonly 属性、
from() 工厂方法的 stub。Action 类
Action 类
生成单一职责的 Action 类的命令。在
App\Actions 命名空间下生成拥有 execute() 方法的类。Livewire 也使用相同机制
Livewire 也使用相同机制
make:livewire 命令由继承 GeneratorCommand 的 MakeCommand 类实现。为了同时生成组件类与 Blade 视图两个文件,它覆写了 handle()。测试
使用 Orchestra Testbench 测试命令是否正确生成文件。相关页面
Laravel 包开发
了解基于 Service Provider 的包开发基础。
使用 Orchestra Testbench 测试 Laravel 包
了解如何构建包的测试基础设施。