以ORM顺序保留IN的顺序

时间:2013-02-15 21:35:08

标签: phalcon

我正在尝试进行查询,我在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做的事情?我似乎无法做我需要做的事。

1 个答案:

答案 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)