PHP 8.1+Symfony5.4下如何组合Swagger属性为自定义属性?
可行,实现步骤如下
PHP 8.1完全支持自定义属性,结合NelmioApiDocBundle的扩展机制,你可以轻松实现类似NestJS的装饰器组合效果,把重复的Swagger注解封装成一个自定义属性。
1. 创建自定义属性类
首先定义一个SwaggerUtils属性,接收标签参数,同时预留开关控制是否包含默认响应:
// src/Annotation/SwaggerUtils.php namespace App\Annotation; use Attribute; #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] class SwaggerUtils { public function __construct( public string $tag, public bool $include400 = true, public bool $include401 = true, public bool $include403 = true, public bool $requireBearer = true ) {} }
2. 编写注解处理器
实现NelmioApiDocBundle的注解处理器接口,当识别到SwaggerUtils属性时,自动生成对应的OA响应、安全验证和标签注解:
// src/Handler/SwaggerUtilsHandler.php namespace App\Handler; use App\Annotation\SwaggerUtils; use Nelmio\ApiDocBundle\Annotation\AnnotationHandlerInterface; use Nelmio\ApiDocBundle\Annotation\Security; use OpenApi\Annotations as OA; use ReflectionMethod; class SwaggerUtilsHandler implements AnnotationHandlerInterface { public function handle($annotation, ReflectionMethod $method, array $annotations, \Nelmio\ApiDocBundle\Describer\ModelRegistry $registry): array { if (!$annotation instanceof SwaggerUtils) { return $annotations; } $newAnnotations = []; // 添加指定标签 $newAnnotations[] = new OA\Tag(name: $annotation->tag); // 添加Bearer安全验证 if ($annotation->requireBearer) { $newAnnotations[] = new Security(name: 'Bearer'); } // 生成400响应 if ($annotation->include400) { $newAnnotations[] = new OA\Response( response: 400, description: 'Bad parameters', content: new OA\JsonContent(example: ['code' => 400, 'message' => 'Bad Request', 'appCode' => 5000]) ); } // 生成401响应 if ($annotation->include401) { $newAnnotations[] = new OA\Response( response: 401, description: 'JWT Token not found (appCode = 5001) or expired (appCode = 5002)', content: new OA\JsonContent(example: ['code' => 401, 'message' => 'JWT Token not found', 'appCode' => 5001]) ); } // 生成403响应 if ($annotation->include403) { $newAnnotations[] = new OA\Response( response: 403, description: 'Insufficient privileges', content: new OA\JsonContent(example: ['code' => 403, 'message' => 'Forbidden', 'appCode' => 5003]) ); } // 合并原有注解与自动生成的注解 return array_merge($annotations, $newAnnotations); } public function supports($annotation): bool { return $annotation instanceof SwaggerUtils; } }
3. 注册处理器服务
在config/services.yaml中注册处理器,让NelmioApiDocBundle能识别并调用它:
services: App\Handler\SwaggerUtilsHandler: tags: - { name: nelmio_api_doc.annotation_handler }
4. 使用自定义属性
现在控制器方法只需一行注解就能替代原来的5个:
#[App\Annotation\SwaggerUtils(tag: 'User')] public function getUserAction() { // 业务逻辑 }
如果需要灵活控制(比如不需要400响应),可以传入参数:
#[App\Annotation\SwaggerUtils(tag: 'User', include400: false)]
原理说明
NelmioApiDocBundle在生成API文档时,会遍历所有注册的annotation_handler。当处理器检测到SwaggerUtils属性时,会自动生成对应的OpenAPI注解并合并到注解列表中,最终效果和手动编写所有注解完全一致。
内容的提问来源于stack exchange,提问作者Taine
相关产品推荐
相关产品推荐

