PHP-在未定义的数组索引上使用+ =运算符

时间:2019-03-28 13:39:30

标签: php mysql

我正在使用从SQL查询中提取的数据稍后在代码中构建两个图表。查询示例如下:

SELECT purchase_location, purchase_item, SUM(purchase_amount) as totalPurchase
FROM purchases
GROUP BY purchase_item_id, purchase_location

不是一个确切的例子,但是想法就在那里。然后,我遍历结果以构建两个数据集。

$locationData = [];
$itemData     = [];
foreach($queryResults as $result) {
   $locationData[$result['purchase_location']] += $result['totalPurchase'];
   $itemData[$result['purchase_item']]         += $result['totalPurchase'];
}

由于我希望从两个不同的角度来看数据,因此我必须使用+ =来获得正确的总数。我的问题是这样的:对数组的未设置索引执行+ =运算符非常慢。我发现如果执行以下操作:

if (isset($locationData['purchase_location'])) {
  $locationData['purchase_location'] += $result['totalPurchase'];
} else {
  $locationData['purchase_location'] = $result['totalPurchase'];
}

第一次使用=来查看索引。这样可以大大加快代码的速度(例如,我的代码从8-10秒的运行时间缩短到不到半秒)。我的问题是,这是正确/最干净的方法吗?

在任何人提到之前,我都知道我可以在这种简单情况下编写查询来处理所有这些问题,这只是一个非常简单的例子来说明问题,即在尚未定义的情况下使用+ =数组索引。

4 个答案:

答案 0 :(得分:1)

我建议已经使用该索引初始化数组,避免进行isset检查并使代码更简洁:

$locationData = ['purchase_location' => 0];
$itemData     = ['purchase_item' => 0];

foreach($queryResults as $result) {
   $locationData['purchase_location'] += $result['totalPurchase'];
   $itemData['purchase_item']          = $result['totalPurchase'];
}

对于我的项目,我通常尝试将isset的使用范围限制为验证无法完全控制的外部来源(例如GET,POST)接收的数据。

既然您已经更新了答案,现在可以在这种情况下使用isset来避免另一个循环来构造数组。

$locationData = [];
$itemData     = [];

foreach($queryResults as $result) {
    if (!isset($locationData[$result['purchase_location']])) {
        $locationData[$result['purchase_location']] = 0;
    }

    if (!isset($itemData[$result['purchase_item']])) {
        $itemData[$result['purchase_item']] = 0;
    }

    $locationData[$result['purchase_location']] += $result['totalPurchase'];
    $itemData[$result['purchase_item']]         += $result['totalPurchase'];
}

如果您使用的是PHP 7+,则可以使用null coalesce ??来简化代码,如下所示:

$locationData = [];
$itemData     = [];

foreach($queryResults as $result) {
    $locationData[$result['purchase_location']] = $result['totalPurchase'] + ($locationData[$result['purchase_location']] ?? 0);
    $itemData[$result['purchase_item']] = $result['totalPurchase'] + ($itemData[$result['purchase_item']] ?? 0);
}

答案 1 :(得分:1)

您可以尝试以下操作:

$locationData = [];
$itemData     = [];
foreach($queryResults as $result) {
   $locationData[$result['purchase_location']] = ($locationData[$result['purchase_location']]??0) + $result['totalPurchase'];
   $itemData[$result['purchase_item']]         = ($itemData[$result['purchase_item']]??0) + $result['totalPurchase'];
}

但是我认为将所有内容分别初始化为零是更干净,更明显的方法:

foreach($queryResults as $result) {
   $locationData[$result['purchase_location']] = 0;
   $itemData[$result['purchase_item']]         = 0;
}

,然后在另一个循环中进行加法工作。

答案 2 :(得分:0)

对于您的问题,是的,您需要先创建此索引,然后再向该索引添加+ =。

而不是每次迭代都检查它,因此只需在foreach循环之前对其进行配置,然后该索引将退出,您将能够对+ =和多数民众赞成进行累加

HashMap

答案 3 :(得分:0)

  

我的问题是,这是正确/最干净的处理方式吗?

没有示例数据和预期结果,很难知道您追求的结果。
有根据的猜测是使用MySQL WITH ROLLUP GROUP BY Modifier来获得总记录。

SELECT purchase_location, purchase_item, SUM(purchase_amount) as totalPurchase
FROM purchases
GROUP BY purchase_item_id, purchase_location WITH ROLLUP