You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP:将API返回对象转换为嵌套数组时遇到结构异常问题

问题:将Salesforce AggregateResult集合转换为以月份名为键的嵌套数组

我从Salesforce API获取了大量AggregateResult类型的SObject对象集合,想把它们转换成以月份名为键的嵌套数组,但目前写的代码生成的结构不符合预期——只有第一个元素用月份名作为键,其余元素都是数字索引,求帮忙解决!


API返回的SObject示例

SObject Object ( [type] => AggregateResult [fields] => stdClass Object ( [expr0] => 12 [Name] => Performance Reviews [Status] => Closed - Approved [expr1] => 30 ) ) 
SObject Object ( [type] => AggregateResult [fields] => stdClass Object ( [expr0] => 12 [Name] => Performance Reviews [Status] => Closed - Attempted [expr1] => 11 ) ) 
SObject Object ( [type] => AggregateResult [fields] => stdClass Object ( [expr0] => 12 [Name] => Performance Reviews [Status] => Closed - Contact Declined [expr1] => 13 ) )

目标嵌套数组结构

Array ( 
    [January] => Array ( 
        [0] => Array ( [0] => January [1] => Closed - Approved [2] => 28 ) 
        [1] => Array ( [0] => January [1] => Closed - Approved [2] => 28 ) 
    ) 
)

当前代码

$query = "SELECT CALENDAR_MONTH(closedDate), recordType.name,status,count(id) FROM case WHERE owner.name ='" . $SFName . "' AND recordType.name IN('DT Case','Performance Reviews') AND closedDate = LAST_N_MONTHS:6 GROUP BY CALENDAR_MONTH(closedDate),recordType.Name,status ORDER BY CALENDAR_MONTH(closedDate)"; 
$counter = 0; 
$mprArray = array(); //instantiate our Array 
$response = $mySforceConnection->query($query); 
$queryResult = new QueryResult($response); 
foreach ($queryResult->records as $case) { 
    //turn our query Result into an Obj 
    $sObject = new SObject($case); 
    $recordType = $sObject->Name; 
    $status = $sObject->Status; 
    $month = $sObject->expr0; 
    $count = $sObject->expr1; 
    //this is a filter to weed out a portion of the cases. 
    if ($recordType == "Performance Reviews") { 
        foreach($sObject as $record) { 
            //change the month's number to a month's name 
            $dateObj = DateTime::createFromFormat('!m', $month); 
            $monthName = $dateObj->format('F'); 
            // Create the nested array, it should end up looking like $mprArray[January]. 
            // This is a dynamic name since we're creating an array for each status that exists in performance Reviews 
            $mprArray[$monthName] = array($monthName,$status,$count); 
            // Trying to append our nested array onto the $mprArray so we can work with it later. 
            array_push($mprArray,$mprArray[$monthName]); 
        } 
    } 
    //increase counter 
    $counter = $counter++; 
} 
} catch (Exception $e) { 
    print_r($mySforceConnection->getLastRequest()); 
    echo $e->faultstring; 
}

错误输出结果

Array ( 
    [January] => Array ( [0] => January [1] => Closed - Contact Declined [2] => 15 ) 
    [0] => Array ( [0] => January [1] => Closed - Approved [2] => 28 ) 
)

解决方案

问题分析

你的代码有两个核心问题:

  1. 不必要的内层循环:foreach($sObject as $record)完全多余,$sObject是单个记录对象,循环它会导致重复处理,还容易出错
  2. 错误的数组赋值方式:
    • $mprArray[$monthName] = array(...)每次循环都会覆盖掉之前的月份数组,而不是追加新元素
    • array_push($mprArray, $mprArray[$monthName])直接把元素加到根数组层级,导致出现数字索引的条目

修正后的代码

把循环部分改成下面这样:

$query = "SELECT CALENDAR_MONTH(closedDate), recordType.name,status,count(id) FROM case WHERE owner.name ='" . $SFName . "' AND recordType.name IN('DT Case','Performance Reviews') AND closedDate = LAST_N_MONTHS:6 GROUP BY CALENDAR_MONTH(closedDate),recordType.Name,status ORDER BY CALENDAR_MONTH(closedDate)"; 
$mprArray = array(); // 初始化结果数组
$response = $mySforceConnection->query($query); 
$queryResult = new QueryResult($response); 

foreach ($queryResult->records as $case) { 
    $sObject = new SObject($case); 
    $recordType = $sObject->Name;
    $status = $sObject->Status;
    $month = $sObject->expr0;
    $count = $sObject->expr1;

    // 只处理Performance Reviews类型的记录
    if ($recordType == "Performance Reviews") {
        // 将月份数字转换为完整月份名称(比如12→December)
        $dateObj = DateTime::createFromFormat('!m', $month);
        $monthName = $dateObj->format('F');
        
        // 如果当前月份的数组还不存在,先初始化为空数组
        if (!isset($mprArray[$monthName])) {
            $mprArray[$monthName] = [];
        }
        
        // 把当前状态的统计数据追加到对应月份的数组中
        $mprArray[$monthName][] = [$monthName, $status, $count];
    }
}

说明

  • 去掉了多余的内层循环和无用的$counter变量
  • 每次处理记录时,先检查月份对应的数组是否存在,不存在则初始化
  • 使用$mprArray[$monthName][] = ...的方式,将新的统计条目追加到对应月份的数组里,而不是覆盖
  • 最终生成的结构就是你想要的:月份名为键,每个键对应一个包含所有相关状态数组的嵌套数组

内容的提问来源于stack exchange,提问作者StavenCross

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:47:17