10

Using CakePHP 2.0 here. The title is a bit misleading, so to clear things up - I have session array which is populated with ids of products as user adds them to cart. So this array goes like [0] => 25, [1] => 70 etc. Let's say this array is called $products.

What I want to ask is is there some possibility to have array which I get by using 'find' model's function ('conditions' => array('Product.id' => $products)) to be sorted not by some of Model.field values (as in 'order' option), but by $products array indices, so that when I render the products content in view I would get all those products in cart sorted in such sequence as user were adding them.

Here's an example - Session array $products:

[0] => 35,
[1] => 15,
[2] => 25

Then I pass this array to conditions of find function:

$list = $this->Product->find('all', array('conditions' => array('Product.id' => $products)));

In the end $list gives me array which sorted by product.id. So instead of having:

[0] => Array
    (
        [Product] => Array
            (
                [id] => 35 )),
[1] => Array
        (
            [Product] => Array
                (
                    [id] => 15 )),

[2] => Array
        (
            [Product] => Array
                (
                    [id] => 25 ))

I get:

[0] => Array
    (
        [Product] => Array
            (
                [id] => 15 )),
[1] => Array
        (
            [Product] => Array
                (
                    [id] => 25 )),
[2] => Array
        (
            [Product] => Array
                (
                    [id] => 35 ))

So far all the answers doesn't solve my problem. Please, pay closer attention to the example I gave, it's very simple, but the answers provided are in different key.

Again, I need final array $list to be sorted by indices of session array $products, but I get $list sorted by Product.id field, even though I didn't specify any 'find(array('order'=> ...))' at all and even tried to set it to false.

4

6 回答 6

2

不想听起来粗鲁,但对我的问题的所有回答都是关于如何按产品 ID 排序我的数组(这显然不是我问的)或关于执行不合适的手动 sql 查询的建议。似乎我无法正确描述我需要什么,但我试图尽可能清楚,抱歉。

在试图找到如何“禁用蛋糕”时,我偶然发现了一个解决方案。所以基本上你需要做的是有一个数组(我们称之为$queue)在其中保存产品 ID,因为它们被添加到购物车,然后在查找模型函数(或分页)中的“订单”选项中,你应该提供它喜欢:

'order'=>array('FIELD(Product.id,'.implode(',', $queue).')')

$queue可能看起来像这样,例如:

[queue] => Array
        (
            [0] => 51
            [1] => 1
            [2] => 11
        )

最后你得到$list数组,其中产品的顺序与$queue中的相同。如果你没有指定 'order' 那么你会得到你的$list数组,如下所示:

 [queue] => Array
            (
                [0] => 1
                [1] => 11
                [2] => 51
            )
于 2012-04-20T16:21:46.227 回答
0

我想不出一个简单的 SQL 查询可以根据参数列表对结果进行排序。

所以最简单的可能是在从数据库中获取记录后重新排序记录。

$records = $this->Product->find('all', array('conditions' => array('Product.id' => $products)));

$sorted_records = array();
foreach($records as $record)
{
  $key = array_search($record['Product']['id'], $products);
  $sorted_records[$key] = $record;
}

ksort($sorted_records);

debug($sorted_records);
于 2012-04-19T14:09:37.877 回答
0

这是有效的 SQL,不知道如何让 cakephp 呈现它,但我认为它会解决您的订购问题:

SELECT * FROM product WHERE id IN (35, 15, 25) ORDER BY id = 35 DESC, id = 15 DESC, id = 25

于 2012-04-19T14:11:36.133 回答
0

如果我理解正确,您需要对模型结果进行排序,或者换句话说,在查询上设置一个顺序以以任意方式排序。

这里有两个选项:

  1. 指定排序。不熟悉 Cake 但您需要生成的 mysql 是:(order by id = 25 desc, id = 70 desc, id = etc猜测会说尝试order => 'id = 25 desc, id = 70 desc, id = etc')您必须从$products数组中组装。

  2. 创建一个购物篮模型并使用连接查询以正确的顺序获取产品列表(不简单,但可能比依赖会话变量更好)。

更新

我已经注意到并确实解决了您的问题,为您提供了您需要生成的 SQL,以及对 Cake 语法的猜测。查看您发布的解决方案,您的 FIELD(id, x, x, x) 正在做同样的事情,但它是一个更清洁的解决方案。找到它做得很好,不过我会删除你的“无意粗鲁”的评论,因为它们通常看起来有点粗鲁。

于 2012-04-19T14:13:34.540 回答
0

我通常处理此类问题的方法是使用内置于 Cake 的 Set 类通过 Product ID 对 $list 进行索引。所以

$list = Set::combine($list, '{n}.Product.id', '{n}.Product');

然后使用您的购物车 ($products) 循环,这已经是您想要的顺序

foreach($products as $prod) echo $list[$prod]['Product']['name'];

希望这可以帮助。

于 2012-04-20T02:35:25.840 回答
0

我不熟悉 cake 或它的数据库层,但也许你可以添加一点 sql。

相关的 sql 类似于

order by field(myTable.myID, 35, 15, 25)
-- or alternatively, more cross database compatible
order by case when myTable.myID = 35 then 1
              when myTable.myID = 15 then 2
              when myTable.myID = 25 then 3
         end

然而,最通用的方法是在 php 代码中重新排序。

$products = array(35,15,25);//the ordered array
$records = array_flip($products);
foreach ($list as $row) {
    $id = $row['Product']['id'];
    $records[$id] = $row;
}
print_r($records);
于 2012-04-19T14:17:18.067 回答