0

我正在尝试进行查询,在其中保留 IN 语句中的 ID 顺序。我似乎无法使用 Model Manage Query Builder 或标准的 ORM 'order' 数组参数来做到这一点。我错过了什么吗?我不断得到:

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 做我想做的事情?看来我将无法做我需要做的事情。

4

1 回答 1

1

不幸的是,如前所述,这在 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)
于 2015-01-22T15:08:58.547 回答