laravel 5 中不推荐直接用原生 curl 发送 json 请求,应优先使用内置 guzzle 客户端;若必须手写 curl,需正确设置 content-type: application/json、json_encode() 数据并校验编码结果,避免空体或头体不匹配。

在 Laravel 5 中,不推荐直接用原生 cURL 发送 application/json 请求(尤其在应用层),因为框架已提供更安全、易维护的封装方式。但若确实需要底层控制(如调试、对接特殊服务、绕过 Guzzle 限制等),可使用 PHP 原生 cURL,并正确设置 JSON 头和数据格式。
手动配置 cURL 发送 JSON 数据
关键点:设置 Content-Type: application/json,并确保请求体是合法 JSON 字符串(用 json_encode() 处理)。
示例代码(可在控制器或服务类中使用):
$data = ['name' => 'John', 'email' => 'john@example.com'];
$jsonData = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/users');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData)
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($response === false) {
throw new \Exception('cURL error: ' . curl_error($ch));
}
return response()->json([
'status' => 'sent',
'code' => $httpCode,
'body' => json_decode($response, true)
]);
更推荐:用 Guzzle HTTP Client(Laravel 5.1+ 内置)
Laravel 5.1 起默认集成 Guzzle(通过 guzzlehttp/guzzle),支持链式调用、自动 JSON 编码、异常处理,更简洁可靠。
- 发送 JSON 自动序列化:传数组给
json选项,Guzzle 自动设 header 并 encode - 无需手动管理
Content-Length或json_encode - 内置异常捕获(
GuzzleHttp\Exception\RequestException)
示例:
use GuzzleHttp\Client;
$client = new Client();
try {
$response = $client->post('https://api.example.com/users', [
'json' => ['name' => 'John', 'email' => 'john@example.com']
]);
return response()->json([
'success' => true,
'data' => $response->getBody()->getContents()
]);
} catch (\GuzzleHttp\Exception\RequestException $e) {
\Log::error('API request failed', ['error' => $e->getMessage()]);
return response()->json(['error' => 'Request failed'], 500);
}
注意 Content-Type 和数据格式的匹配
常见错误:
- 传了
json数组但 header 写成application/x-www-form-urlencoded - 手动
json_encode后,header 漏写或拼错(如写成application/json; charset=utf-8虽然通常可接受,但部分老旧 API 会拒收) - 数组含非 UTF-8 字符导致
json_encode返回false,后续 cURL 发送空体
建议加简单校验:
$jsonData = json_encode($data, JSON_UNESCAPED_UNICODE);
if ($jsonData === false) {
throw new \InvalidArgumentException('Invalid JSON data: ' . json_last_error_msg());
}
如果必须用 Facade 或辅助函数封装
可新建一个服务类(如 App\Services\HttpClientService),统一处理 JSON 请求逻辑,避免控制器里重复写 cURL 设置。也可用 Laravel 的 Http facade(需 Laravel 7+;Laravel 5 不原生支持,需升级或自行封装)。
对 Laravel 5 用户,最稳妥路径仍是:优先用 Guzzle,仅在极特殊场景才手写 cURL,并务必验证 JSON 编码结果与 header 一致性。











