CakePHP数据库查询在不同的机器上没有显示相同的结果(数组关联与数组索引)

时间:2016-08-02 15:54:57

标签: php cakephp

我正在使用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;
}

1 个答案:

答案 0 :(得分:0)

不同版本的MySQL

虽然我找不到具体的参考资料,但是之前已经出现了,几乎可以肯定是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(以及问题中的查询)的存在建议不必要地使用查询。