使用CURL调用API返回“Malformed JSON”问题排查求助
排查POST请求返回"Malformed JSON"错误的解决方案
嘿,我帮你梳理下代码里的问题点,大概率是这些细节导致了看似莫名其妙的JSON格式错误提示:
1. URI处理错误(最核心的问题)
你这段代码里对请求URI的处理完全不符合Buckaroo API的要求:
$uri = strtolower(urlencode('https://testcheckout.buckaroo.nl/json/transaction'));
Buckaroo的HMAC签名验证只需要请求路径的小写形式,也就是/json/transaction,而不是把整个URL做URL编码。你现在生成的$uri会变成https%3a%2f%2ftestcheckout.buckaroo.nl%2fjson%2ftransaction,这和API端预期的URI完全不匹配,会直接导致签名验证失败——很多时候API会返回模糊的错误提示,比如你遇到的"Malformed JSON",但实际问题出在认证环节。
修正方式很简单:
$uri = strtolower('/json/transaction');
2. 变量复用引发的潜在混淆
你重复使用了$post变量,虽然当前逻辑没直接影响JSON发送,但很容易在后续修改代码时出问题:
$post = json_encode($postArray); // 初始是JSON字符串 // ... 中间处理MD5 $post = base64_encode($md5); // 被覆盖成MD5的base64值
建议把变量拆分重命名,让逻辑更清晰:
$postJson = json_encode($postArray); $md5Raw = md5($postJson, true); $postHash = base64_encode($md5Raw); // 后续构造HMAC时用$postHash $hmacSource = $websiteKey . 'POST' . $uri . $time . $nonce . $postHash;
3. 验证JSON的实际发送内容
虽然你打印的JSON看起来没问题,但建议把JSON内容单独存变量,同时确认字节长度:
$postJson = json_encode($postArray); echo "实际发送的JSON:<pre>" . $postJson . "</pre>"; echo "JSON字节长度:" . strlen($postJson) . "<br>";
确保Content-Length头的值和这个strlen结果完全一致(你当前代码里是对的,但变量复用很容易破坏这个对应关系)。
4. 开启curl调试模式排查细节
如果以上修改后还是有问题,开启curl的调试日志,看看实际发送的请求头和内容是否符合预期:
curl_setopt($curl, CURLOPT_VERBOSE, true); $debugLog = fopen('php://temp', 'w+'); curl_setopt($curl, CURLOPT_STDERR, $debugLog); // 执行请求后打印调试信息 $result = curl_exec($curl); rewind($debugLog); echo "<pre>CURL调试日志:" . stream_get_contents($debugLog) . "</pre>";
通过日志你能看到是否存在请求头错误、JSON内容截断等问题。
总结
优先修正URI的处理方式,这几乎肯定是导致你遇到错误的原因。其他几点是为了让代码更健壮,避免后续出现类似问题。
内容的提问来源于stack exchange,提问作者Kevin.a
相关产品推荐
相关产品推荐

