蓝易云 - PHP用CURL发送Content-type为application/json的POST请求方法
2026/4/28 17:33:50 网站建设 项目流程

下面给你一套在 PHP 里用 cURL 发送 Content-Type: application/json 的 POST 请求的“标准企业写法”:结构清晰、可复用、可排障,适合直接丢进生产代码库🙂


一、最关键的点(先把坑堵死)

  1. 请求体必须是 JSON 字符串:用json_encode()生成,而不是http_build_query()

  2. 必须显式设置 Content-Type:Content-Type: application/json; charset=utf-8

  3. 建议带上 Content-Length:部分网关/安全设备更“挑剔”。

  4. 服务端返回如果是 JSON,建议设置 Accept: application/json,便于协商。


二、可直接复用的完整示例(含超时、错误处理、响应解析)✅

<?php $url = "https://api.example.com/v1/order/create"; $payload = [ "user_id" => 10001, "amount" => 99.50, "remark" => "test", ]; // 1) 将数组编码成 JSON 字符串(这是 application/json 的核心) $jsonBody = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if ($jsonBody === false) { throw new RuntimeException("JSON 编码失败: " . json_last_error_msg()); } $ch = curl_init($url); // 2) 关键请求头:明确告诉服务端“我发的是 JSON”,也表明“我期望 JSON 响应” $headers = [ "Content-Type: application/json; charset=utf-8", "Accept: application/json", "Content-Length: " . strlen($jsonBody), ]; curl_setopt_array($ch, [ CURLOPT_POST => true, // 使用 POST 方法 CURLOPT_POSTFIELDS => $jsonBody, // POST 请求体:必须是 JSON 字符串 CURLOPT_HTTPHEADER => $headers, // 设置请求头 CURLOPT_RETURNTRANSFER => true, // 返回响应内容为字符串(不直接输出) CURLOPT_CONNECTTIMEOUT => 5, // 连接超时(秒) CURLOPT_TIMEOUT => 15, // 总超时(秒) CURLOPT_FAILONERROR => false, // 不让 4xx/5xx 直接导致 curl_exec 返回 false(方便读响应体排错) ]); $responseBody = curl_exec($ch); // 3) 网络层错误:DNS、连接失败、TLS 握手失败等 if ($responseBody === false) { $errno = curl_errno($ch); $error = curl_error($ch); curl_close($ch); throw new RuntimeException("cURL 请求失败 [{$errno}]: {$error}"); } // 4) 协议层信息:HTTP 状态码、Content-Type 等 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); // 5) 按需解析 JSON 响应(如果服务端确实返回 JSON) $data = null; if (is_string($contentType) && stripos($contentType, "application/json") !== false) { $data = json_decode($responseBody, true); } // 6) 业务层处理示例:按 HTTP 状态码做分流 if ($httpCode >= 200 && $httpCode < 300) { // 成功:优先用解析后的数组;解析失败则回退原始响应 var_dump($data ?? $responseBody); } else { // 失败:把响应体也带上,便于排查(网关经常会回 JSON 错误详情) throw new RuntimeException("HTTP 请求失败,状态码={$httpCode},响应={$responseBody}"); }

逐段解释(对应你最常踩的点)

  • json_encode(...):把 PHP 数组变成 JSON 字符串,这一步决定服务端能不能按 JSON 解析。

  • CURLOPT_POSTFIELDS:你传进去什么,HTTP Body 就是什么。要发 JSON,就必须传 JSON 字符串。

  • CURLOPT_HTTPHEADER:这里把 Content-Type 定死为application/json,否则服务端可能按表单解析导致字段丢失。

  • CURLOPT_RETURNTRANSFER:拿到响应字符串,方便你写日志、做重试、做告警。

  • CURLINFO_HTTP_CODE:把网络成功与业务成功分开看,避免“curl 成功但业务失败还当成功”。🙂


三、工作流程图(你可以当排障 checklist)

准备 payload(数组) ↓ <span style="color:red">json_encode</span> → 得到 JSON 字符串 ↓ 设置请求头:<span style="color:red">Content-Type: application/json</span> ↓ cURL POST 发送(超时、返回响应) ↓ 检查:curl_exec 是否 false(网络层) ↓ 检查:HTTP 状态码(协议层) ↓ 按 Content-Type 判断是否 json_decode(业务层)

四、原理/参数对照表(把配置变成可控资产)

推荐值作用常见问题
Content-Typeapplication/json; charset=utf-8声明 Body 格式不设置会被当表单解析
CURLOPT_POSTFIELDSJSON 字符串实际请求体传数组会被转成a=1&b=2
Acceptapplication/json期望响应格式响应非 JSON 时解析失败
CONNECTTIMEOUT3~5s连接超时DNS/TLS 卡住拖垮线程
TIMEOUT10~30s总超时无上限会把 PHP-FPM 拖死

你拿去直接用的“结论”

只要做到两件事:
1)json_encode()得到 JSON Body;
2)请求头带上Content-Type: application/json
再配好超时与错误分层(网络/HTTP/业务),这就是一套可在生产稳定跑的写法。🚀

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询