You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现匹配registrationId与hash双字段的API自定义过滤器?

解决方案

情况1:通过两个独立查询参数(registrationId和hash)同时过滤

这种方式最直观,用户通过?registrationId=xxx&hash=yyy的形式传递参数,过滤器会自动生成AND条件匹配两个字段。

修改你的RegistrationSearchFilter代码如下:

final class RegistrationSearchFilter extends AbstractFilter
{
    protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
    {
        // 只处理我们需要的两个字段
        if (!in_array($property, ['registrationId', 'hash'])) {
            return;
        }

        $alias = $queryBuilder->getRootAliases()[0];
        // 生成唯一参数名,避免多参数冲突
        $paramName = $queryNameGenerator->generateParameterName($property);
        
        // 添加AND条件并绑定参数值
        $queryBuilder->andWhere(sprintf('%s.%s = :%s', $alias, $property, $paramName))
                     ->setParameter($paramName, $value);
    }

    public function getDescription(string $resourceClass): array
    {
        $description = [];
        $fields = [
            'registrationId' => '匹配注册ID',
            'hash' => '匹配哈希值'
        ];

        foreach ($fields as $property => $desc) {
            $description[$property] = [
                'property' => $property,
                'type' => Type::BUILTIN_TYPE_STRING,
                'required' => false,
                'description' => $desc,
                'openapi' => [
                    'example' => $property === 'registrationId' ? 'REG-202405' : 'a1b2c3d4e5f6',
                    'allowReserved' => false,
                    'allowEmptyValue' => false,
                    'explode' => false,
                ],
            ];
        }

        return $description;
    }
}

关键修正点:

  • 移除原代码中对search属性的判断,改为处理实体注解指定的registrationId和hash字段
  • 为每个字段生成唯一参数名,避免参数冲突
  • 正确绑定参数值到查询中,解决原代码参数未赋值的问题
  • 生成对应OpenAPI文档描述,方便前端使用

情况2:通过单个查询参数传递两个字段值

如果需要通过单个参数(比如?search=REG-202405:a1b2c3d4e5f6)传递两个值,可按以下方式修改:

final class RegistrationSearchFilter extends AbstractFilter
{
    protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
    {
        if ($property !== 'search') {
            return;
        }

        // 按分隔符拆分参数值(这里用冒号,可根据需求调整)
        [$registrationId, $hash] = explode(':', $value, 2);
        // 格式不合法则跳过
        if (empty($registrationId) || empty($hash)) {
            return;
        }

        $alias = $queryBuilder->getRootAliases()[0];
        // 生成唯一参数名
        $regParam = $queryNameGenerator->generateParameterName('registrationId');
        $hashParam = $queryNameGenerator->generateParameterName('hash');
        
        // 添加AND条件并绑定两个参数
        $queryBuilder->andWhere(sprintf('%s.registrationId = :%s AND %s.hash = :%s', $alias, $regParam, $alias, $hashParam))
                     ->setParameter($regParam, $registrationId)
                     ->setParameter($hashParam, $hash);
    }

    public function getDescription(string $resourceClass): array
    {
        return [
            'search' => [
                'property' => 'search',
                'type' => Type::BUILTIN_TYPE_STRING,
                'required' => false,
                'description' => '同时匹配registrationId和hash,格式为「registrationId:hash」',
                'openapi' => [
                    'example' => 'REG-202405:a1b2c3d4e5f6',
                    'allowReserved' => false,
                    'allowEmptyValue' => false,
                    'explode' => false,
                ],
            ],
        ];
    }
}

注意:这种方式需要修改实体注解为#[ApiFilter(RegistrationSearchFilter::class, properties: ['search'])],确保过滤器监听search参数。


原代码问题总结

  1. 过滤器逻辑错误:原代码只处理search属性,但实体注解指定的是registrationId和hash,导致过滤逻辑从未执行
  2. 参数未绑定:原代码的WHERE子句使用了:search和:hash参数,但未通过setParameter赋值,导致查询报错
  3. 文档描述不符:原代码生成的是正则过滤的描述,与实际需求的精确匹配不符

内容的提问来源于stack exchange,提问作者Richard Bridge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:25:22