不幸的是,如前所述,这在 Phalcon 中缺少一个功能。
看看这个函数,我把它放到了我的ModelBase抽象类中,它是我所有模型的父类。它使用 PhQL 变量绑定,因此可以安全地处理直接用户输入。
您可以重新实现自定义\Phalcon\Mvc\Model\Criteria但这个解决方案似乎更容易使用,至少对我来说。
模型库摘要
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)