在Symfony 5.1+ApiPlatform 2.5环境下,如何基于数组类型的Symfony Workflow Place过滤数据库API输出对象?
解决ApiPlatform自定义过滤器中Symfony Workflow状态(数组存储)的过滤问题
太懂你这种找不到简洁方案的痛苦了!针对你在ApiPlatform 2.5搭配Symfony 5.1时遇到的Symfony Workflow状态过滤难题,这里有个能彻底摆脱冗余字段的优雅解决办法:
问题回顾
你的核心痛点是:Workflow的状态在数据库里以数组形式存储(比如Status = { "OPEN": 1 }),直接用QueryBuilder的=、LIKE或IN都没法实现精准匹配,只能临时加个StatusText字符串字段绕开问题,但频繁用Workflow的话这种方案实在太冗余。
优雅解决方案
我们可以借助Doctrine的JSON函数扩展,直接对数据库中的JSON格式状态字段进行查询,步骤如下:
1. 安装JSON函数扩展包
首先安装scienta/doctrine-json-functions,它能让Doctrine支持SQL的JSON相关函数:
composer require scienta/doctrine-json-functions
2. 关键注意事项
⚠️ 划重点:存储Workflow状态时,一定要用Doctrine的json_array类型,而不是普通的array类型!这样数据库会以标准JSON格式存储数据,才能支持后续的JSON函数查询。
3. 修改自定义过滤器的QueryBuilder逻辑
直接用JSON_EXTRACT函数提取JSON字段里的状态值做匹配,替换你之前的尝试代码:
$rootAlias = $queryBuilder->getRootAliases()[0]; // 这里以匹配OPEN状态值为1为例,其他状态只需修改'$.OPEN'为对应路径即可 $jsonExtractCondition = "JSON_EXTRACT(".$rootAlias.".Status, '$.OPEN') = 1"; $queryBuilder->andWhere($jsonExtractCondition) ->leftJoin(sprintf('%s.Objs', $rootAlias), 'o') ->andWhere('o.Profile = :p') ->setParameter('p', $profile);
不管是OPEN、CLOSING还是CLOSED这类状态,只需要调整JSON_EXTRACT里的JSON路径(比如'$.CLOSING'),就能轻松实现不同状态的过滤需求,彻底告别冗余字段~
内容的提问来源于stack exchange,提问作者vesirem
相关产品推荐
相关产品推荐

