如何修改API Platform中数组类型的查询参数格式?
API Platform 数组查询参数格式自定义方案
原生支持情况
API Platform 默认遵循PHP原生的查询参数解析规则,仅支持/customers?cars[]=audi&cars[]=mercedes&cars[]=bmw这类带[]后缀的数组参数格式,没有内置配置项可以直接切换为逗号、竖线分隔的数组参数格式。
自定义格式实现方案
你提到的DeserializeListener是可行的实现路径,除此之外也可以通过请求事件监听器更简单的实现需求,两种常用方案如下:
- 方案1:
kernel.request事件监听器(优先级高于DeserializeListener即可)
在请求进入核心处理流程前,提前解析转换分隔符格式的参数,示例实现如下:
<?php // src/EventListener/QueryArrayParamConverterListener.php namespace App\EventListener; use Symfony\Component\HttpKernel\Event\RequestEvent; class QueryArrayParamConverterListener { public function __invoke(RequestEvent $event): void { $request = $event->getRequest(); // 仅处理GET请求的查询参数 if (!$request->isMethod('GET')) { return; } // 配置需要支持分隔符格式的数组参数名 $targetParams = ['id', 'cars']; foreach ($targetParams as $paramName) { $rawValue = $request->query->get($paramName); // 跳过非字符串格式、已经是数组的参数 if (empty($rawValue) || is_array($rawValue)) { continue; } // 支持逗号、竖线两种分隔符 $parsedArray = preg_split('/[,|]/', trim($rawValue)); // 替换请求中的参数值 $request->query->set($paramName, $parsedArray); } } }
配置服务时指定事件优先级高于api_platform.listener.request.deserialize即可生效。
- 方案2:扩展DeserializeListener
如果你仅需要在资源反序列化阶段处理参数,可以重写DeserializeListener的反序列化前置逻辑,在参数映射到对象前完成分隔符拆分转换,适配业务规则。
如果需要OpenAPI文档自动展示该参数格式,可以为对应资源的查询参数添加配置,声明style: form, explode: false即可和Swagger规范对齐。
内容的提问来源于stack exchange,提问作者Vincent Decaux
相关产品推荐
相关产品推荐

