如何将CSV格式的CURL响应转换为关联式JSON结构?
问题
我需要将API返回的CSV格式CURL响应转换为JSON,但当前输出里表头和对应数据相互脱节,没法直接关联。我要让每个商家的数据和对应的表头(比如Clicks字段)绑定,方便遍历获取指定字段值。
当前实现代码:
$curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'URLHERE', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', )); $res = curl_exec($curl); $array = array_map("str_getcsv", explode("\n", $res)); print json_encode($array);
当前输出结果:
[ [ "Report Name", "Sales and Activity Report" ], [ "Date Run", "6/8/23" ], [ "Filters", "Transaction Date >= 6/1/23", "Transaction Date <= 6/8/23", "Network ID IN 1", "Time Zone = GMT" ], [ null ], [ "ID", "Name", "Impressions", "Clicks", "Click Through Rate", "Sales" ], [ "3184", "website.com", "0", "19,146", "0", "8,100" ] ]
API返回的原始样本数据:
Report Name,Sales and Activity Report Date Run,6/8/23 Filters,Transaction Date >= 6/1/23,Transaction Date <= 6/8/23,Network ID IN 1,Time Zone = GMT ID,Advertiser Name,Impressions,Clicks,Click Through Rate,Sales 3184,"website.com",0,"19,146",0,"8,100"
解决方案
核心思路是先分离CSV中的元数据(报告名称、日期、筛选条件)和商家数据区域,然后将商家数据行与对应的表头映射为关联数组,这样就能直接通过字段名(如Clicks)访问对应值。
修改后的代码:
$curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'URLHERE', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', )); $res = curl_exec($curl); curl_close($curl); // 记得关闭curl资源 // 按行分割并过滤空行和无效行 $lines = explode("\n", $res); $lines = array_filter($lines, function($line) { $trimmed = trim($line); return !empty($trimmed) && $trimmed !== ','; }); // 转换为CSV数组 $csvData = array_map('str_getcsv', $lines); $reportMeta = []; $merchantHeaders = []; $merchantData = []; $merchantSectionStarted = false; foreach ($csvData as $row) { // 跳过空行(已过滤,做双重保险) if (empty(array_filter($row))) continue; // 识别商家数据的表头行(以ID开头) if ($row[0] === 'ID') { $merchantHeaders = $row; $merchantSectionStarted = true; continue; } if ($merchantSectionStarted) { // 将数据行与表头映射为关联数组 $merchantItem = array_combine($merchantHeaders, $row); // 可选:格式化带千分位的数值为纯数字 $merchantItem['Clicks'] = (int)str_replace(',', '', $merchantItem['Clicks']); $merchantItem['Sales'] = (float)str_replace(',', '', $merchantItem['Sales']); $merchantData[] = $merchantItem; } else { // 收集报告元数据 if (count($row) >= 2) { $reportMeta[$row[0]] = implode(', ', array_slice($row, 1)); } } } // 组合最终结果,包含元数据和商家数据 $result = [ 'report_meta' => $reportMeta, 'merchants' => $merchantData ]; // 输出格式化后的JSON print json_encode($result, JSON_PRETTY_PRINT);
代码说明
- 过滤无效行:去除空行和仅含逗号的无效行,避免后续处理出错。
- 分离数据区域:通过行首是否为
ID识别商家数据的表头,之前的行统一作为报告元数据收集。 - 映射关联数组:用
array_combine将表头与数据行绑定,生成以字段名为键的关联数组,直接通过$item['Clicks']即可访问对应值。 - 数值格式化(可选):对带千分位逗号的数值做格式转换,变成纯数字类型,方便后续计算或展示。
最终输出示例:
{ "report_meta": { "Report Name": "Sales and Activity Report", "Date Run": "6/8/23", "Filters": "Transaction Date >= 6/1/23, Transaction Date <= 6/8/23, Network ID IN 1, Time Zone = GMT" }, "merchants": [ { "ID": "3184", "Advertiser Name": "website.com", "Impressions": "0", "Clicks": 19146, "Click Through Rate": "0", "Sales": 8100 } ] }
内容的提问来源于stack exchange,提问作者jord49
相关产品推荐
相关产品推荐

