vzina / attributes
Webman plugin vzina/attributes
Installs: 5
Dependents: 2
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/vzina/attributes
Requires
- php: ^8.1
- ext-pcntl: *
- illuminate/filesystem: >=9.0
- illuminate/pipeline: >=9.0
- illuminate/support: >=9.0
- nikic/php-parser: ^5.0
- php-di/phpdoc-reader: ^2.2
- webman/cache: ^2.0
- webman/console: ^2.1
- webman/event: ^1.0
- webman/redis: ^2.1
- workerman/webman-framework: ^2.0
Requires (Dev)
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2026-01-08 03:11:14 UTC
README
一、工具简介
Attributes 是适配 Webman 框架的轻量级 PHP 注解工具,通过简单的注解(Attribute)语法,快速实现依赖注入、配置注入、定时任务、事件监听等功能,无需手动编写重复代码,方便hyperf用户过渡使用。
二、环境要求
- PHP 8.1+
- Webman 框架 >= 2.1
三、安装插件
composer require -W vzina/attributes
# 热更启动,建议仅在开发环境使用
./webman server:watch start
四、基础使用
1. 依赖注入(@Inject)
自动注入类属性,支持懒加载(使用时才实例化)。
namespace app\controller; use Vzina\Attributes\Attribute\Inject; use app\Service\UserService; class UserController { // 懒加载注入UserService #[Inject(lazy: true)] private ?UserService $userService = null; public function index() { // 调用注入的服务方法 return $this->userService->getUser(1); } }
2. 配置注入(@Value)
从配置文件中读取值并注入到属性。
namespace app\service; use Vzina\Attributes\Attribute\Value; class OrderService { // 读取配置 app.name,默认值为 "webman" #[Value(key: 'app.name', default: 'webman')] private string $appName; public function getAppName() { return $this->appName; // 直接使用注入的配置值 } }
3. 定时任务(@Crontab)
通过注解定义定时任务。
composer require -W workerman/crontab:^1.0
namespace app\crontab; use Vzina\Attributes\Attribute\Crontab; // 每1分钟执行一次 #[Crontab(rule: '* * * * *')] class OrderStats { // 固定执行方法:handle public function handle() { echo "订单统计任务执行:" . date('Y-m-d H:i:s') . PHP_EOL; } }
4. 事件监听(@Listener)
监听指定事件,触发时自动执行处理逻辑。
namespace app\listener; use Vzina\Attributes\Attribute\Listener; use Webman\Event\Event; // 监听 "order.created" 事件 #[Listener(event: 'order.created')] class OrderCreated { // 事件处理方法:handle public function handle($params, $event) { $orderId = $params['order_id']; echo "订单 {$orderId} 已创建" . PHP_EOL; } } // 触发事件(任意位置) // Event::dispatch('order.created', ['order_id' => 1001]);
5. 注册路由(@Controller)
通过注解定义路由规则。
namespace app\controller; use app\routes\RequestMapping; use Vzina\Attributes\Attribute\Route\AutoController; use Vzina\Attributes\Attribute\Route\Controller; use Vzina\Attributes\Attribute\Route\Resource; // 注册路由 #[Controller(prefix: 'order', options: ['middleware' => []])] class OrderController { #[RequestMapping(path: 'index', options: ['middleware' => [], 'name' => '路由名称,默认:类名.方法名'])] public function index() { return json([]); } } // 自动路由 #[AutoController(prefix: 'bar', options: ['middleware' => []])] class BarController { public function index() { return json([]); } } // 资源型路由 #[Resource(prefix: 'bar2')] class Bar2Controller { public function index() { return json([]); } }
6. 缓存功能(@Cacheable)
通过注解定义缓存逻辑
namespace app\services; use Vzina\Attributes\Attribute\Cacheable; class OrderService { #[Cacheable( prefix: "cache", // 缓存前缀 value: "#{params.order_id}", // 参数模板,格式:#{方法参数名},数组及对象:#{方法参数名.元素key/属性名} ttl: 60, // 缓存时间 group: "redis", // 缓存策略,默认:config('cache.default') collect: false, // 是否收集缓存key,可用于统一管理,仅支持redis缓存驱动 evict: false, // true,仅删除缓存 put: false, // true,仅写入缓存 aheadSeconds: 0, // 缓存提前更新时间 lockSeconds: 10, // 更新缓存锁时间,仅支持redis缓存驱动 offset: 0, // 缓存偏移量 )] public function handle(array $params) { return time(); } }
7. 枚举(@Constants)
namespace app\constants; use Vzina\Attributes\Attribute\Constants; use Vzina\Attributes\Attribute\ConstantsTrait; #[Constants] class OrderStats { use ConstantsTrait /** * @Message("完成") */ const SUCCESS = 1; } // 使用方法 //OrderStats::getMessage(OrderStats::SUCCESS) #[Constants] enum OrderStatsEnum { use ConstantsTrait /** * @Message("完成") */ case SUCCESS = 1; } // 使用方法 //OrderStatsEnum::getMessage(OrderStatsEnum::SUCCESS)
8. 切面(@Aspect)
注意使用切面前需要生成项目的自动加载(autoload)文件
composer dump-autoload -o
namespace app\aspects; use GuzzleHttp\Client; use Vzina\Attributes\Ast\ProceedingJoinPoint; use Vzina\Attributes\Attribute\Aspect; use Vzina\Attributes\Attribute\AspectInterface; #[Aspect] class ClientAspect implements AspectInterface { public array $classes = [ Client::class . '::request' ]; public function process(ProceedingJoinPoint $proceedingJoinPoint) { var_dump(__METHOD__); return $proceedingJoinPoint->process(); } } // 使用方法 $client = new Client(); $r = $client->get('https://www.baidu.com'); var_dump($r->getStatusCode()); // 输出结果: //string(33) "app\aspects\ClientAspect::process" //int(200)
9. 自定义进程(@Process)
namespace app\process; use Vzina\Attributes\Attribute\Process; #[Process(name: 'test-worker')] class Test { public function onWorkerStart(): void { } }
9. 依赖服务(@Depend)
namespace app; use support\Container;use Vzina\Attributes\Attribute\Depend; interface TestInterface {} #[Depend(id: TestInterface::class)] class Test { } // 使用 $test = Container::get(TestInterface::class); var_dump($test);