我正在尝试进行查询,我在IN语句中保留id的顺序。我似乎无法使用模型管理查询生成器或标准ORM'顺序'数组参数。我错过了什么吗?我一直在说:
UNEXPECTED TOKEN IDENTIFIER(, NEAR TO 'id`enter code here`,17743,16688,16650
这是我的模特经理:
$query = $this->modelsManager->createQuery('SELECT * FROM Projects WHERE id IN ('.implode(',', array_keys($finalIterations)).')
ORDER BY FIELD(id,'.implode(',', array_keys($finalIterations)).'');
很明显,PhQL不喜欢FIELD关键字。有没有办法让我做我想用PhQL做的事情?我似乎无法做我需要做的事。
答案 0 :(得分:1)
不幸的是,如前所述,Phalcon中缺少一项功能。
看看这个函数,我把它放到我的 ModelBase 抽象类中,它是我所有模型的父类。它使用PhQL变量绑定,因此可以安全地处理直接用户输入。
您可以重新实现自定义 \ Phalcon \ Mvc \ Model \ Criteria 但这个解决方案似乎更容易使用,至少对我而言。
ModelBase摘要
public function appendCustomOrder( \Phalcon\Mvc\Model\CriteriaInterface &$criteria, $orderField, array &$orderValues = [] ) {
if(!empty($orderValues)) {
$queryKeys = $bindParams = [];
foreach($orderValues as $key => $id) {
$queryKey = 'pho'.$key;
$queryKeys[] = ':'.$queryKey.':';
$bindParams[$queryKey] = $id;
}
// TODO: add support for multiple orderBy fields
$criteria->orderBy('FIELD('.$orderField.','.implode(',',$queryKeys).')');
// there's no 'addBind' function, need to merge old parameters with new ones
$criteria->bind( array_merge( (array) @$criteria->getParams()['bind'], $bindParams ) );
}
}
控制器使用
$projectIDs = [17743, 16688, 16650];
$projectsModel = new Projects();
$criteria = $projectsModel->query->inWhere( 'id', $projectIDs );
$projectsModel->appendCustomOrder( $criteria, 'id', $projectIDs );
$projectsData = $criteria->execute();
这将生成与此类似的有效PhQL语法:
SELECT `projects`.`id` AS `id`, `projects`.`title` AS `title`
FROM `projects`
WHERE `projects`.`id` IN (:phi0, :phi1, :phi2)
ORDER BY FIELD(`projects`.`id`, :pho0, :pho1, :pho2)