2

我在使用 CakePHP 1.3 查找信息时遇到了一个奇怪的问题。让我们以这个 dbschema 为例:

id 是 int(11) PRIMARY auto_increment 数量是 float(10,2) NULL 状态是 ENUM(Completed, Removed, Pending)

id  amount  status
1   100.00  Completed
2   100.00  Removed
3   100.00  Completed
4   100.00  Completed
5   100.00  Pending

当使用 Cake'sfind从这个表中检索数据时,我使用这个查询:

$this->Testtable->find('all', array(
    'conditions' => array(
        'status LIKE ' => 'Removed',
        'status LIKE ' => 'Pending',
        'status LIKE ' => 'Completed'
    )
)) 

查看这个查询,我假设Cake 会返回匹配所有这些条件的所有行(这在 SQL 中是完全可以接受的),但是它只使用最后一个条件并返回WHERE status LIKE 'Completed'

我运行了一个测试,它正确返回了所有行(我知道无论如何这是一种更“正确”的查询方式):

'conditions' => array(
    'status' => array('Removed', 'Pending', 'Completed')        
)

以相反的例子为例,我想返回所有删除或待处理的行:

'conditions' => array(
    'status !=' => 'Removed',
    'status !=' => 'Pending'
)

此查询返回所有带有 CompletedRemoved 的行,因为它只侦听最后一条语句。我认为发生这种情况是因为 Cake 没有将这些搜索条件连接到查询中,而是覆盖了基于“字段”的条件status !=。我可以通过在其中任何一种情况下添加一个空格来证明这一理论!=,从而仅创建已确认记录的所需结果。

谁能告诉我为什么蛋糕会这样做?由于这是在 SQL 中做的合法事情,我认为 Cake 没有理由不允许你这样做。有人知道这个问题是否在较新版本的 Cake 中得到解决?

4

2 回答 2

1

我想这归结为这样一个事实,即在一天结束时,我正在根据该键重新分配数组值,而这实际上根本不是 CakePHP 的错。我查看了Cake'smodel.php并发现了这个:

$query = array_merge(compact('conditions', 'fields', 'order', 'recursive'), array('limit' => 1));

我做了一个测试:

$array = array(
'conditions' => array(
    'test' => 'yes',
    'test' => 'no'
)
);

$var = 'hello';
$c = compact('array', 'var');
print_r($c);

如上所述,仅从键compact接收值。我假设使用将变量/数组合并到查询中会递归地将条件数组中的相似键合并到最后一个指定的键中,但事实证明,就现场重新定义而言,它甚至没有做到这一点。notestcompactyes

我想这是 PHP 而不是 Cake 的限制,但它仍然是我没有想到的事情,将来应该以某种方式(如果还没有的话)以不同的方式完成。

编辑

我又进行了几次测试。我将相同的条件封装在它们自己的数组中,然后像 Cake 的 find 函数那样比较它们。使用compact(Cake 这样做)包含相同键的数组保持不变,但是使用array_merge,第一个键被第二个键覆盖。compact我想在这种情况下,Cake 使用它而不是array_merge合并其查询条件是一件非常非常好的事情。

$array = array(
    array('test' => 'yes'),
    array('test' => 'no')
);

$m = array_merge($array[0], $array[1]);
$c = compact('array');

print_r($c);
print_r($m);

结果:

Array
(
    [array] => Array
        (
            [0] => Array
                (
                    [test] => yes
                )

            [1] => Array
                (
                    [test] => no
                )

        )

)
Array
(
    [test] => no
)

虽然这显然是您从根本上编写 PHP 代码的方式中的一个简单问题,但在使用 Cake 语法编写时,条件会相互覆盖并不是天生显而易见的......

于 2013-11-11T23:35:11.367 回答
1

基本 PHP:不要两次使用相同的数组键

'conditions' => array(
    'status LIKE ' => 'Removed',
    'status LIKE ' => 'Pending',
    'status LIKE ' => 'Completed'
)

应该

'conditions' => array(
    'status LIKE' => array('Removed', 'Pending', 'Completed'),
)

对于任何其他数组键也是如此。

请注意,阵列的一些快速调试揭示了这一点。另请参阅有关相同问题或其他领域的大量其他 stackoverflow 问题,基础研究可能会为您指明这个方向。先看看那里可以帮助在更短的时间内解决问题。

于 2013-11-12T09:18:47.273 回答