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

TYPO3 v12 Repository查询约束报错:logicalAnd参数类型不匹配

TYPO3 v12 Extbase Repository 查询约束数组报错解决办法

问题背景

自TYPO3 v12版本起,Repository查询中约束的使用方式与之前版本不同。以下是相关查询代码:

public function findByDate(
    $dateFrom = null, 
    $dateTill = null, 
    $isAdmin = false, 
    $tags = [], 
    $keyword = ''
): QueryResultInterface
{
    $query = $this->createQuery();
    $query->getQuerySettings()->setIgnoreEnableFields(TRUE);
    $query->getQuerySettings()->setEnableFieldsToBeIgnored(['starttime','endtime']);

    $constraints = [];
    if ($keyword != '') {
        $constraints[] = $query->like('titel', '%'.$keyword.'%' );
    }else{
        if (isset($dateFrom) && isset($dateTill)) {
            $constraints[] = $query->logicalAnd(
                $query->lessThan('startdate', $dateTill->getTimestamp()),
                $query->greaterThan('startdate', $dateFrom->getTimestamp()),
            );
        }
    }

    if (count($tags) > 0) {
        $constraints[] = $query->logicalOr(
            $query->in('tags.uid', $tags)
        );
    }

    if ($isAdmin == false) {
        $constraints[] = $query->equals('share', true);
    }

    $query->matching($query->logicalAnd($constraints));
    return $query->execute();
}

执行上述代码时触发如下错误:

TYPO3\CMS\Extbase\Persistence\Generic\Query::logicalAnd(): Argument #1 must be of type TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface, array given

已知单条件查询、直接传入两个约束的logicalAnd方法均可正常运行,需确认是否仍可使用约束数组方式查询及解决报错方案。

解决方案

TYPO3 v12 中依然可以使用约束数组,但调用logicalAnd的方式发生了变化:

  • v12之前logicalAnd支持直接传入数组参数,v12开始该方法要求传入单个或多个ConstraintInterface实例,不再接受数组。
  • 解决办法是使用PHP的展开运算符(...),将数组元素作为独立参数传入logicalAnd。

修改后的核心代码

将原代码中的:

$query->matching($query->logicalAnd($constraints));

替换为:

if (!empty($constraints)) {
    $query->matching($query->logicalAnd(...$constraints));
} else {
    // 无约束时匹配所有记录,或根据业务需求调整
    $query->matching($query->logicalTrue());
}

完整优化后的代码

public function findByDate(
    $dateFrom = null, 
    $dateTill = null, 
    $isAdmin = false, 
    $tags = [], 
    $keyword = ''
): QueryResultInterface
{
    $query = $this->createQuery();
    $query->getQuerySettings()->setIgnoreEnableFields(true);
    $query->getQuerySettings()->setEnableFieldsToBeIgnored(['starttime','endtime']);

    $constraints = [];
    if ($keyword !== '') {
        $constraints[] = $query->like('titel', '%' . $keyword . '%');
    } else {
        if (isset($dateFrom) && isset($dateTill)) {
            $constraints[] = $query->logicalAnd(
                $query->lessThan('startdate', $dateTill->getTimestamp()),
                $query->greaterThan('startdate', $dateFrom->getTimestamp())
            );
        }
    }

    if (count($tags) > 0) {
        // 原代码用logicalOr包裹单个in约束冗余,直接加入数组即可
        $constraints[] = $query->in('tags.uid', $tags);
    }

    if (!$isAdmin) {
        $constraints[] = $query->equals('share', true);
    }

    if (!empty($constraints)) {
        $query->matching($query->logicalAnd(...$constraints));
    } else {
        $query->matching($query->logicalTrue());
    }

    return $query->execute();
}

额外说明

  • 必须处理空约束场景:如果$constraints为空,直接调用logicalAnd会报错,需先判断数组是否为空,无约束时可使用logicalTrue()匹配所有记录。
  • 移除冗余逻辑:原代码中用logicalOr包裹单个in约束是多余的,直接将in结果加入约束数组即可。

内容的提问来源于stack exchange,提问作者Carlos Sampaio Peredo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:36:11