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

使用Curl下载JSON文件后json_decode返回空数组问题求助

问题:Curl下载150MB JSON文件后json_decode解析失败,直接读取网页文件却正常

我需要下载一个150MB的JSON文件,用Curl下载后调用json_decode返回空数组;但直接读取网页端的同一份文件时,解析完全正常。

之前遇到Invalid argument supplied for foreach()错误,把$data_apartments = json_decode($json_apartments,true);改成$data_apartments = (array)json_decode($json_apartments,true);也没用。添加JSON错误检测后,得到提示:Array - Syntax error, malformed JSON。


Curl下载代码

<?php
$url = 'https://localhost.8888/apartments.json';
$destFile = 'aparts.json';

$fp = fopen($destFile, 'w+b');
if (false === $fp) {
    throw new RuntimeException ( 'fopen() failed.   last error: ' . return_var_dump ( error_get_last () ) );
}
$ch = curl_init();
if (false === $ch) {
    throw new RuntimeException ( 'curl_init() failed.   last error: ' . return_var_dump ( error_get_last () ) );
}

ecurl_setopt($ch, CURLOPT_URL,$url);
ecurl_setopt($ch, CURLOPT_FILE, $fp); // write curl response to file
ecurl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
ecurl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
ecurl_setopt($ch, CURLOPT_VERBOSE, true);
ecurl_setopt($ch, CURLOPT_STDERR, $fp);
ecurl_exec($ch);
curl_close($ch);
fclose($fp);

function ecurl_setopt ( /*resource*/$ch , int $option , /*mixed*/ $value ):bool{
    $ret=curl_setopt($ch,$option,$value);
    if($ret!==true){
        //option should be obvious by stack trace
        throw new RuntimeException ( 'curl_setopt() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
    }
    return true;
}
function ecurl_exec ( /*resource*/$ch)/*:mixed depending on CURLOPT_RETURNTRANSFER*/{
    $ret=curl_exec($ch);
    if($ret===false){
        throw new RuntimeException ( 'curl_exec() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
    }
    return $ret;
}

function return_var_dump(){
    $args = func_get_args ();
    ob_start ();
    call_user_func_array ( 'var_dump', $args );
    return ob_get_clean ();
}
?>

json_decode处理代码

<?php
$json_apartments = file_get_contents('aparts.json');
$data_apartments = (array)json_decode($json_apartments,true);

foreach($data_apartments as $jsons_apartments) 
{
$_id = $json_apartments['_id'];
$area_balconies_total = $json_apartments['area_balconies_total'];
$area_given = $json_apartments['area_given'];
}
?>

JSON文件示例

[
{
    "_id": "1cv",
    "area_balconies_total": 0,
    "area_given": 57.2
}
]

问题根源及解决办法

  1. 核心问题:JSON文件被Curl日志污染
    你开启了CURLOPT_VERBOSE调试模式,并且把CURLOPT_STDERR指向了和下载文件同一个句柄$fp,导致Curl的调试日志(比如* Trying 127.0.0.1:8888...这类内容)直接写入到aparts.json中,破坏了原本的JSON结构,所以json_decode解析失败。

  2. 修复步骤

    • 分离日志和下载文件:单独创建日志文件句柄,把Curl错误输出指向该文件,不要和下载目标文件共用句柄:
      // 新增日志文件句柄
      $logFp = fopen('curl_download.log', 'w');
      ecurl_setopt($ch, CURLOPT_STDERR, $logFp);
      // 执行Curl后关闭日志句柄
      ecurl_exec($ch);
      fclose($logFp);
      
    • 删除废弃选项:CURLOPT_BINARYTRANSFER在PHP 7.1及以上版本已废弃,无需设置,直接删除该行代码。
    • 修复语法错误:原代码中url = 'https://localhost.8888/apartments.json';缺少$符号,改为$url = 'https://localhost.8888/apartments.json';。
  3. 验证修复
    重新下载后,打开aparts.json检查开头是否有Curl日志内容,若没有则说明文件正常。此时json_decode($json_apartments,true)会直接返回数组,无需强制转成数组,foreach循环也能正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:35:59