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

在Doctrine中用自定义DQL表达式构建OR条件时遇错如何解决?

解决Doctrine Criteria OR表达式结合自定义JSON_CONTAINS函数的报错问题

问题原因

你当前的代码直接把SQL字符串传给Criteria::expr()->orX(),但这个方法要求传入的是Doctrine的表达式对象(实现ExpressionInterface),而非原始SQL字符串,因此会触发No expression given to CompositeExpression错误。

修正方案

下面提供两种安全且有效的实现方式,同时避免SQL注入风险:

方案1:基于Criteria构建表达式并绑定参数

private function filterAgeGroups(array $ageGroups) {
    $expr = Criteria::expr();
    $criterias = [];
    
    foreach ($ageGroups as $index => $ageGroup) {
        // 构建JSON_CONTAINS的比较表达式
        $jsonCondition = $expr->comparison(
            "JSON_CONTAINS(g.ageGroupIds, :ageGroup$index)",
            '=',
            1
        );
        $criterias[] = $jsonCondition;
    }
    
    return $expr->orX(...$criterias);
}

使用时需要在QueryBuilder中绑定对应参数:

$ageGroups = [/* 你的年龄组数据 */];
$ageCriteria = $this->filterAgeGroups($ageGroups);
$qb->addCriteria($ageCriteria);

// 循环绑定每个参数
foreach ($ageGroups as $index => $ageGroup) {
    $qb->setParameter("ageGroup$index", (string)$ageGroup);
}

方案2:直接通过QueryBuilder的Expr构建OR条件

如果你的场景不需要单独返回Criteria,也可以直接在QueryBuilder中操作:

private function addAgeGroupFilter($qb, array $ageGroups) {
    $expr = $qb->expr();
    $conditions = [];
    
    foreach ($ageGroups as $index => $ageGroup) {
        // 用expr()->eq包裹自定义函数调用
        $conditions[] = $expr->eq(
            "JSON_CONTAINS(g.ageGroupIds, :ageGroup$index)",
            1
        );
    }
    
    if (!empty($conditions)) {
        $qb->andWhere($expr->orX(...$conditions));
        // 绑定参数
        foreach ($ageGroups as $index => $ageGroup) {
            $qb->setParameter("ageGroup$index", (string)$ageGroup);
        }
    }
    
    return $qb;
}

调用方式:

$qb = $entityManager->createQueryBuilder();
// 其他查询构建逻辑...
$this->addAgeGroupFilter($qb, [/* 年龄组数组 */]);

关键注意事项

  • 绝对不要直接把$ageGroup拼接到SQL字符串中,必须通过参数绑定(:ageGroup$index)避免SQL注入风险,这和你第二段正常工作的代码逻辑保持一致。
  • orX()方法仅接受Doctrine表达式对象,不能直接传原始SQL字符串,这是你之前报错的核心原因。

内容的提问来源于stack exchange,提问作者David Schilling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:15:40