首页 > 解决方案 > PHP - 在未定义的数组索引上使用 += 运算符

问题描述

我稍后在我的代码中使用从 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 秒的运行时间缩短到不到半秒)。我的问题是,这是处理这个问题的正确/最干净的方法吗?

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

标签: phpmysql

解决方案


我建议已经使用该索引初始化数组,避免需要进行 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 合并 ??来简化代码,如下所示:

$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);
}

推荐阅读