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

