
本文详解如何在 PHP 中构造并发送结构复杂的嵌套多维 JSON 对象(如消息 API 所需格式),避免因误用 http_build_query() 导致数据损坏,强调使用原生 JSON 字符串 + Content-Type: application/json 的标准实践。
本文详解如何在 php 中构造并发送结构复杂的嵌套多维 json 对象(如消息 api 所需格式),避免因误用 `http_build_query()` 导致数据损坏,强调使用原生 json 字符串 + `content-type: application/json` 的标准实践。
在 PHP 中向 RESTful API(尤其是消息类服务,如 CM.com)提交深度嵌套的 JSON 数据时,一个常见误区是:将 JSON 字符串先 json_decode() 成 PHP 数组/对象,再用 http_build_query() 编码为 URL 表单格式(application/x-www-form-urlencoded)。这会导致结构完全丢失——数组变平、嵌套对象塌陷、JSON 特有的类型(如空数组、null 值)被错误转换,最终 API 接收的是无效或截断的数据。
正确的做法是:保持 JSON 的原始字符串形态,通过 cURL 直接发送,并显式声明请求头 Content-Type: application/json。以下是完整、可运行的实现方案:
✅ 正确发送嵌套 JSON 的 PHP 示例
<?php
// 1. 定义原始 JSON 字符串(注意:必须是合法 JSON 格式,键名和字符串值需双引号)
$json_object = '{
"messages": {
"authentication": {
"productToken": "your_product_token_here"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback Text for SMS"
},
"to": [{"number": "00316012345678"}],
"from": "00316098765432",
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{"text": "A text message with *bold* formatting in a speech bubble."},
{"text": "Another speech bubble"},
{
"media": {
"mediaName": "and an image",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
}
}]
}
}';
// 2. 初始化 cURL
$ch = curl_init();
$url = 'https://api.example.com/v1/messages'; // 替换为目标 API 地址
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json_object, // ⚠️ 直接传入 JSON 字符串,非数组!
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json'
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false, // 生产环境请启用证书验证
]);
// 3. 执行请求并处理响应
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new RuntimeException("cURL Error: $error");
}
if ($http_code >= 200 && $http_code < 300) {
$result = json_decode($response, true);
echo "✅ 请求成功!响应数据:<pre class="brush:php;toolbar:false;">" . htmlspecialchars(print_r($result, true)) . "";
} else {
echo "❌ 请求失败,HTTP 状态码:$http_code"; echo "响应体:
" . htmlspecialchars($response) . ""; } ?>
? 关键要点说明
- 不要 json_decode() 后再 http_build_query():http_build_query() 是为表单提交设计的,会把嵌套结构强行扁平化(如 msg[0][to][0][number]),API 端无法还原原始 JSON 结构。
- CURLOPT_POSTFIELDS 必须接收字符串:直接传 $json_object(即 JSON 字符串),而非 json_decode($json_object) 得到的对象或数组。
- 必须设置 Content-Type: application/json:这是服务端识别并正确解析 JSON 的关键依据;缺失该头可能导致 415 Unsupported Media Type 错误。
-
JSON 字符串需严格校验:建议使用 json_last_error() 验证:
$decoded = json_decode($json_object, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new InvalidArgumentException('Invalid JSON: ' . json_last_error_msg()); } - 生产环境安全提示:禁用 CURLOPT_SSL_VERIFYPEER => false;应配置 CA 证书路径或使用系统默认证书。
? 进阶:动态构建复杂 JSON(推荐方式)
若 JSON 数据来自变量组合,建议用 PHP 数组构造后 json_encode(),而非拼接字符串:
$data = [
'messages' => [
'authentication' => ['productToken' => $_ENV['PRODUCT_TOKEN']],
'msg' => [[
'body' => ['type' => 'auto', 'content' => 'Hello'],
'to' => [['number' => '+316012345678']],
'from' => '+316098765432',
'allowedChannels' => ['WhatsApp'],
'richContent' => [
'conversation' => [
['text' => 'Hi there!'],
['media' => [
'mediaName' => 'logo',
'mediaUri' => 'https://example.com/logo.png',
'mimeType' => 'image/png'
]]
]
]
]]
]
];
$json_payload = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// 然后传入 CURLOPT_POSTFIELDS...? 提示:json_encode() 默认输出 UTF-8 字符串,配合 JSON_UNESCAPED_UNICODE 可避免中文被转义,提升可读性与兼容性。
立即学习“PHP免费学习笔记(深入)”;
遵循以上方法,即可稳定、准确地发送任意深度嵌套的 JSON 数据至现代 Web API,彻底规避因格式误用引发的数据损坏问题。











