Phalcon 5中如何实现带OR条件的betweenWhere查询?
Phalcon 5 实现指定条件查询的两种正确方式
一、PHQL 写法(解决参数错误问题)
你遇到的“Invalid parameter number: parameter was not defined”错误,基本都是参数名不匹配或者漏传参数导致的。以下是正确的PHQL实现,严格对应参数绑定:
$deviceId = 123; // 替换为你的指定device_id $startRange = '2024-01-01 00:00:00'; // 区间起始时间 $endRange = '2024-01-31 23:59:59'; // 区间结束时间 $phql = "SELECT start_date, end_date FROM ItProductiviteeHistory WHERE device_id = :deviceId: AND (start_date BETWEEN :startRange: AND :endRange: OR end_date BETWEEN :startRange: AND :endRange:)"; // 执行查询并绑定参数 $results = $this->modelsManager->executeQuery( $phql, [ 'deviceId' => $deviceId, 'startRange' => $startRange, 'endRange' => $endRange ] );
关键注意点:
- 模型类名
ItProductiviteeHistory要和数据库表it_productivitee_history正确映射(Phalcon默认驼峰命名转下划线表名) - PHQL中的参数名(
:deviceId:这类)必须和绑定数组的键名完全一致,大小写敏感 - 一定要用括号包裹OR条件,保证逻辑优先级:先判断
start_date或end_date在区间内,再和device_id的条件做AND关联
二、Query Builder 写法(实现OR条件)
Query Builder实现时,核心是把OR条件嵌套在AND逻辑里,避免逻辑错误。这里提供两种写法:
写法一:用匿名函数嵌套条件
$deviceId = 123; $startRange = '2024-01-01 00:00:00'; $endRange = '2024-01-31 23:59:59'; $queryBuilder = $this->modelsManager->createBuilder() ->columns(['start_date', 'end_date']) // 指定要查询的字段 ->from('ItProductiviteeHistory') ->where('device_id = :deviceId:', ['deviceId' => $deviceId]) ->andWhere( function($builder) use ($startRange, $endRange) { // 嵌套OR条件:start_date在区间 或者 end_date在区间 $builder->betweenWhere('start_date', $startRange, $endRange) ->orWhere('end_date BETWEEN :start: AND :end:', [ 'start' => $startRange, 'end' => $endRange ]); } ); $results = $queryBuilder->getQuery()->execute();
写法二:直接使用字符串条件(更简洁)
$deviceId = 123; $startRange = '2024-01-01 00:00:00'; $endRange = '2024-01-31 23:59:59'; $queryBuilder = $this->modelsManager->createBuilder() ->columns(['start_date', 'end_date']) ->from('ItProductiviteeHistory') ->where('device_id = :deviceId:', ['deviceId' => $deviceId]) ->andWhere('(start_date BETWEEN :start: AND :end: OR end_date BETWEEN :start: AND :end:)') ->setBindParams([ 'start' => $startRange, 'end' => $endRange ]); $results = $queryBuilder->getQuery()->execute();
关键注意点:
- 必须用括号包裹OR条件,否则逻辑会变成
(device_id匹配 AND start_date在区间) OR end_date在区间,不符合你的需求 - 重复使用的参数(比如
start和end)只需要绑定一次,Phalcon会自动处理
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

