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
相关产品推荐
相关产品推荐

