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

PHP使用CURLOPT_RETURNTRANSFER获取JSON数据异常求助

问题描述

我正在开发一段PHP代码用于从API获取JSON数据,遇到以下问题:

  • 某一特定URL在代码中返回的$result不为空,但无法用print或echo输出;
  • 该URL在PostMan中可正常返回数据;
  • 其他同类URL在代码和PostMan中均正常工作,无错误返回。

我初步怀疑问题出在curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);或curl_exec上,但排查陷入困境。相关代码如下:

function getRestCall($url, $data = null, $method = self::METHOD_GET)
{
    $curl = curl_init();
    
    curl_setopt($curl, CURLOPT_URL, $url);
    
    printf('<h2>URL</h2>' . $url);
    // Set authentication parameters
    curl_setopt($curl, CURLOPT_USERPWD, $this->username . ':' . $this->password);

    // Don't send as json when attaching files to tasks.
    if (is_string($data) || empty($data['file']))
    {
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'content-Type: application/json'
        )); // Send as JSON
    }

    // Dont print result
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
   
    // Set maximum timeout limit
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $this->timeout);
    curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
    curl_setopt($curl, CURLOPT_FAILONERROR, true);

    // Don't verify SSL connection
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);

    // Define methods
    curl_setopt($curl, CURLINFO_HEADER_OUT, true);

    if ($method == self::METHOD_POST)
    {
        curl_setopt($curl, CURLOPT_POST, true);
    }
    elseif ($method == self::METHOD_PUT)
    {
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
    }
    elseif ($method == self::METHOD_DELETE)
    {
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
    }
    
    // Define post data if we have the correct method
    if (!is_null($data) && ($method == self::METHOD_POST || $method == self::METHOD_PUT))
    {
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    
    try
    {
        $return = curl_exec($curl);

        if ($this->debug)
        {
            $info = curl_getinfo($curl);
            echo '<pre>';
            print_r($info);
           
            echo '</pre>';
            if ($info['http_code'] == 0)
            {
                echo '<br />error num: ' . curl_errno($curl);
                echo '<br />error: ' . curl_error($curl);
            }

            if (!is_null($data))
            {
                echo '<br />Sent info:<br /><pre>';
                print_r($data);
                echo '</pre>';
            }
        }
        
    }
    catch(Exception $e)
    {
        $return = null;
        if ($this->debug)
        {
            echo "Exception caught: " . $e->getMessage();
        }
    }

    if ($return === false)
    {
         printf('<h2>Return value is error, SHOW!!:  </h2>'); 
         $return = curl_error($curl);
         //printf('<h2>Return value is not empty, SHOW!!:  </h2>'. $return);
    }else
     {
         printf('<h2>no error</h2>');
     }
    curl_close($curl);
    return $return;
}
排查方案

1. 检查返回内容的编码与特殊字符

有些JSON内容可能包含不可打印控制字符,或者编码与当前页面不一致,导致echo/print无法正常渲染。可以通过以下方式检测:

  • 输出内容长度确认:var_dump(strlen($return));
  • 转义特殊字符后输出:echo htmlspecialchars($return);
  • 解析为数组后输出:print_r(json_decode($return, true));(如果返回的是合法JSON)
  • 查看原始二进制内容:echo bin2hex($return);,对比PostMan返回内容的十六进制值,确认数据是否一致

2. 验证CURLOPT_RETURNTRANSFER的有效性

临时注释掉curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);,让curl直接输出响应内容。如果此时能正常显示,说明问题出在后续处理逻辑,而非curl获取阶段。

3. 核对HTTP响应头信息

在debug模式下,打印响应的Content-Type:echo curl_getinfo($curl, CURLINFO_CONTENT_TYPE);,确认返回的内容类型是否为application/json,是否包含正确的编码声明(如charset=utf-8)。编码不匹配可能导致浏览器无法正确显示内容。

4. 排查CURLOPT_FAILONERROR的影响

你设置了CURLOPT_FAILONERROR为true,若API返回4xx/5xx状态码但实际包含内容,curl会直接返回false。虽然你说$result不为空,但可以临时关闭该选项测试:curl_setopt($curl, CURLOPT_FAILONERROR, false);

5. 对齐PostMan与curl的请求头

PostMan会自动添加User-Agent、Accept等请求头,而你的代码仅设置了Content-Type。可以在代码中模拟PostMan的请求头:

curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    'content-Type: application/json',
    'User-Agent: PostmanRuntime/7.32.3',
    'Accept: */*'
));

6. 检查输出缓冲干扰

如果代码中开启了输出缓冲(如ob_start()),可能导致内容被缓冲无法及时显示。可以在输出前执行ob_end_flush();,或者用var_dump(ob_get_contents());检查缓冲内容。

内容的提问来源于stack exchange,提问作者Nguyen Tat Manh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:24:20