
本文详解在 php 中调用 rest api 时,如何正确将关联数组(即 json 对象)作为某个请求参数的值发送,重点解决因内容类型不匹配导致的参数丢失问题。
本文详解在 php 中调用 rest api 时,如何正确将关联数组(即 json 对象)作为某个请求参数的值发送,重点解决因内容类型不匹配导致的参数丢失问题。
在与第三方 API 集成时,常遇到文档要求某参数(如 data)的值必须为一个 JSON 对象(例如 { "Email": "user@example.com", "URL": "https://github.com/..." })。此时若错误地使用 application/x-www-form-urlencoded 编码并嵌套对象,API 往往无法解析该字段——表面无报错,但服务端收到的 data 为空,正如提问者所遇。
根本原因在于:http_build_query() 会将嵌套数组扁平化为字符串(如 data[Email]=...),而目标 API 实际期望的是标准 JSON 格式 + Content-Type: application/json 头。PHP 的 json_encode() 才能生成合法、可嵌套的 JSON 字符串。
✅ 正确做法如下(精简、可靠、符合 REST 规范):
<?php $myWORK = [
'Email' => 'MY_EMAIL',
'URL' => 'REPOSITORY_URL',
];
$url = 'https://api.xxxxxxx.com/';
$data = [
'key' => 'MY_API_KEY',
'base' => 'MY_TOKEN',
'data' => $myWORK, // 直接赋值数组,无需 json_decode(json_encode(...))
];
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode($data) // 全量 payload 序列化为 JSON
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === false) {
throw new RuntimeException('HTTP request failed');
}
$response = json_decode($result, true);
print_r($response);
?>
⚠️ 关键注意事项:
- 不要对 $myWORK 做 json_decode(json_encode(...)) 操作:这不仅冗余,还可能因类型转换引发意外(如 stdClass 对象 vs 数组),且完全没必要;
- content-type 必须严格设为 application/json,且 header 中换行符需为 \r\n(stream_context_create 要求);
- http_build_query() 仅适用于表单提交(x-www-form-urlencoded),一旦使用 json_encode(),整个请求体就是 JSON,不能再混用表单编码逻辑;
- 若 API 文档明确要求 data 字段是 JSON 字符串(而非对象),则需 json_encode($myWORK) 后再赋值给 'data' => ...,但绝大多数现代 API 接收的是结构化 JSON 对象,直接嵌套即可。
总结:发送含对象的 POST 请求,核心是「统一编码方式」——全 JSON + application/json 头。保持数据结构原生、避免无谓转换,是确保参数准确送达服务端的关键。











