nzour / symfony-advanced-resolving
Requires
- php: >=8.0
- symfony/serializer-pack: ^1.1
Requires (Dev)
- jetbrains/phpstorm-stubs: ^2022.1
- phpunit/phpunit: ^9.5
- psalm/plugin-symfony: ^3.1
- roave/security-advisories: dev-latest
- symfony/config: ^5.3
- symfony/dependency-injection: ^5.3
- symfony/http-kernel: ^5.3
- symfony/serializer: ^5.3
- vimeo/psalm: ^4.23
This package is auto-updated.
Last update: 2024-09-11 01:11:08 UTC
README
要求
- php >= 8.0
- symfony >= 5.3
安装
composer require nzour/symfony-advanced-resolving
重要:确保包 \AdvancedResolving\AdvancedResolvingBundle 已启用,否则在 bundles.php 中启用它
示例
#1 使用 #[FromQuery] 属性
#[AsController, Route(path: '/foo')] final class FooController { #[Route(methods: ['GET'])] public static function index(#[FromQuery] string $value): JsonResponse { return new JsonResponse([ 'value' => $value, ]); } }
GET {host}/foo?value={value}
#2 使用 #[FromQuery] 属性与不同的参数名
#[AsController, Route(path: '/foo')] final class FooController { #[Route(methods: ['GET'])] public static function index( #[FromQuery(paramName: 'foobar')] string $value, #[FromQuery] int $score, ): JsonResponse { return new JsonResponse([ 'value' => $value, 'score' => $score, ]); } }
GET {host}/foo?foobar={value}&score={score}
#3 使用 #[FromQuery] 与类类型提示
final class FooQuery { public function __construct( public string $value, public int $score, ) { } } #[AsController, Route(path: '/foo')] final class FooController { #[Route(methods: ['GET'])] public static function index(#[FromQuery] FooQuery $fooQuery): JsonResponse { return new JsonResponse($fooQuery); } }
GET {host}/foo?value={value}&score={score}
注意:无法通过附加属性重命名 FooQuery 的属性
#4 使用 #[FromBody]
final class FooCommand { public function __construct( public string $foobar, public int $barfoo, ) { } } #[AsController, Route(path: '/foo')] final class FooController { #[Route(methods: ['POST'])] public static function command(#[FromBody] FooCommand $command): JsonResponse { return new JsonResponse([ 'command' => $command, ]); } }
文档
基于 Symfony's ArgumentValueResolver 流程的功能,因此请确保您的控制器带有 controller.service_arguments 标签或通过 #[AsController] 属性标记。
内置
-
bin/console debug:meta-resolvers- 查看定义的元解析器列表 -
FromBody
使用 symfony 序列化器从纯数据实例化对象,数据默认格式为 json。可以通过以下方式指定其他格式:
#[FromBody(format: XmlEncoder::FORMAT)]。无法全局更改格式。 -
FromQuery
您可以指定不同的参数名
#[FromQuery(paramName: 'foobar')]参数 FromQuery::$disableTypeEnforcement 负责在解析对象时设置 AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT 标志。默认值为 true。
尚未实现
- FromHeader
- FromForm
错误
- Symfony 序列化器异常
- NonNullableArgumentWithNoDefaultValueFromQueryParamsException - 仅适用于 #[FromQuery]。参数不可为 null,没有默认值,并且请求中也没有指定值
- CouldNotCreateInstanceFromQueryParamsException - 与上面类似,但如果参数的类型提示是类
由用户扩展
如果您想创建自己的属性和解析它的算法,请按照以下步骤操作
- 定义您的属性或使用现有的属性
- 定义类服务,实现 MetaResolverInterface
- 方法 supportedAttribute 应返回它支持的属性 class-string
- 使用标签
meta-resolver标记您的服务
限制
-
内置解析器与 Symfony 序列化器 一起工作
-
不与 Symfony 验证器 交互(目前或可能不是)
-
内置属性仅与端点参数一起使用,无法组合属性
final class FooDto { public function __construct( #[FromQuery] public string $foobar, public int $barfoo, ) { } } #[AsController] final class FooController { #[Route(path: '/foo', methods: ['POST']) public function index(#[FromBody] FooDto $dto): void { // ... } }
整个类 FooDto 会从 Body 参数编译。
但是属性 FooDto::$foobar 被标记为 #[FromQuery],解析器不会尝试在查询参数中查找参数 foobar 并将其设置为属性的值。