贝利信息

php如何发起post请求_php发起post请求curl设置【请求】

日期:2026-01-18 00:00 / 作者:雪夜
PHP用cURL发POST请求的关键是CURLOPT_POSTFIELDS值类型决定Content-Type:传数组或http_build_query结果→application/x-www-form-urlencoded,服务端用$_POST接收;传JSON字符串→须手动设Content-Type: application/json,否则需读php://input。

PHP 用 cURL 发起 POST 请求的基本写法

直接调用 curl_init() + curl_setopt() 是最常用、最可控的方式。关键不是“能不能发”,而是参数设对没设对——尤其是 CURLOPT_POSTFIELDS 的值类型,它直接决定服务端收到的是表单数据还是原始 JSON。

curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/login');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['username' => 'test', 'password' => '123']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

POST 请求中 header 设置不生效的常见原因

CURLOPT_HTTPHEADER 看似简单,但几个细节极易踩坑:一是 header 数组必须是字符串数组(['Content-Type: application/json']),不能是关联数组;二是如果用了 CURLOPT_POSTFIELDS 数组,cURL 会自动加 Content-Type,覆盖你手动设的;三是某些服务器(如 Nginx)会过滤掉带下划线的 header 名,比如 X-Request-ID 没问题,X_Request_ID 可能被静默丢弃。

超时、错误处理和连接复用的实际建议

线上环境不设超时等于裸奔,而只设 CURLOPT_TIMEOUT 不够——它控制整个请求周期,但 DNS 解析、TCP 连接、SSL 握手这些前期耗时可能卡死在 30 秒以上。真正健壮的做法是分开设 CURLOPT_CONNECTTIMEOUT_MS(毫秒级)和 CURLOPT_TIMEOUT_MS(推荐都用 *_MS 版本)。

替代方案:file_get_contents() 能不能用?

可以,但限制极多。它依赖 allow_url_fopen=On(很多生产环境禁用),且配置 header 和超时只能靠 stream_context_create(),写法冗长、错误提示模糊,连重定向都得手动处理。唯一优势是不用装 cURL 扩展。

$opts = [
    'http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/json\r\n",
        'content' => json_encode(['id' => 123])
    ]
];
$result = file_get_contents('https://api.example.com/item', false, stream_context_create($opts));
实际项目里,95% 的 POST 场景用 cURL 更稳。真正容易被忽略的,是 CURLOPT_POSTFIELDS 类型与 Content-Type 的严格对应关系——传错类型,后端就收不到数据,还查不出错在哪。