我正在使用CakePHP查询数据库中的一些数据。代码是以老式的方式创建的,直接从字符串执行查询:
$query = "SELECT
SUM(IF(p2.status = 'ACTIVE', p2.stock, 0)) AS total_stock,
Product.*,
Brand.*,
Merchant.*,
Item.*,
Tenant.*
FROM
products p2,
products Product
LEFT JOIN
brands Brand ON Product.brand_id = Brand.id
LEFT JOIN
items Item ON Product.item_id = Item.id
LEFT JOIN
merchants Merchant ON Product.merchant_id = Merchant.id,
tenants Tenant
WHERE
Tenant.id = Product.tenant_id
AND Product.id = ?
AND Product.group_hash = p2.group_hash
GROUP BY Product.id";
$product = $this->queryFirst($query, array($id));
代码工作正常,当我转储$product
变量时,它显示一个像这样的关联数组:
Array ( [0] => Array ( [total_stock] => 0 ) [Product] => Array ( [id] => 23640 [type] => PRODUCT ...
所以稍后我可以做someFunc($product['Product']['id']
并且它仍然正常。
我在恢复机器中尝试了相同的代码,现在当我转储它显示的结果时:
Array ( [0] => Array ( [total_stock] => 0 [id] => 23640 [type] => PRODUCT ... )
当然,当我在恢复时someFunc($product['Product']['id']
显示:
注意:未找到索引:产品
我在生产和恢复机器中检查了CakePHP和PHP的版本。两者的CakePHP版本为2.4
。
生产中的PHP版本为5.5.25
,恢复版本为5.5.34
,因此恢复版本较新,应该不是问题,对吧?
MySQL的版本是
恢复: mysql Ver 14.14 Distrib 5.5.49,debian-linux-gnu(x86_64)使用readline 6.2
和
生产: mysql版本14.14使用readline 6.3分发5.5.42,debian-linux-gnu(x86_64)
我在两者上使用相同的Git分支是肯定的。我相信问题可能在其中一个未版本化的文件中,所以我也检查了两个core.php配置文件,但没有相关的差异。
有什么想法吗?
更新:
queryFirst
函数的定义如下:
function queryFirst($query, $params = array())
{
$data = $this->query($query, $params);
if (isset($data[0])) {
return $data[0];
}
return $data;
}
答案 0 :(得分:0)
虽然我找不到具体的参考资料,但是之前已经出现了,几乎可以肯定是MySQL的版本。
这种行为归结为CakePHP询问mysql“这个字段属于哪个表的方式?”对于结果集,确定使用的数组键 - 答案因MySQL的版本而异。在2.4中,相关方法为getColumnMeta,在1.x中为mysql_fetch_field。当使用视图时,这也表现出来,MySQL有时会返回源表名,有时会返回视图名称,有时甚至不返回任何内容。
通过问题中的查询,结果集中的第二个字段为id
(产品ID)。在一台服务器上getColumnMeta
为表返回Product
,在另一台服务器上返回null,最终结果是查询的返回数组结构不同。
相关代码是here(这属于哪个表格?)和here(重新索引结果为[table][field]
索引)如果您想环顾四周并确认/否认这是否是你案件中的原因。
这种不良行为也是CakePHP在3.x中停止这种行为的主要原因,并始终使用以下形式的查询:
SELECT Foos.id AS `Table__field`
字段别名确定结果中使用的数组索引。
您可以通过别名字段或显式返回字段(不使用.*
),可能来影响这一点。
或者,将query
转换为find('first', $params)
调用 - 因为CakePHP可以使用它自己的dogfood :)。除非绝对必要,否则应避免使用query
方法,queryFirst
(以及问题中的查询)的存在建议不必要地使用查询。