stream_context_create配置HTTP需将选项嵌套在'http'键下,如method、header(含\r\n)、timeout(秒,支持浮点)、content(POST数据)、ignore_errors等;HTTPS需正确设置ssl选项或cafile。

stream_context_create 里怎么传 HTTP 请求头和超时
直接用 stream_context_create 配置 HTTP 请求,核心是传一个二维数组,第一层键是协议名(比如 http),第二层才是具体选项。别写成平铺一维数组,那会静默失效。
常见错误是把 timeout 写在顶层,或者漏掉 http 大括号:
// ❌ 错误:timeout 在顶层,不生效
$ctx = stream_context_create(['timeout' => 5]);
// ✅ 正确:必须套在 'http' 下
$ctx = stream_context_create([
'http' => [
'method' => 'GET',
'header' => "User-Agent: php-cli\r\nAccept: application/json\r\n",
'timeout' => 5,
'ignore_errors' => true,
]
]);
-
timeout单位是秒,支持浮点数(如0.5),但底层依赖系统 socket 层,太小可能被截断或忽略 -
header值必须带\r\n换行,不能只用\n;多个头用字符串拼接,别传数组(PHP 不自动 join) -
ignore_errors设为true才能让file_get_contents在 4xx/5xx 时仍返回响应体,否则直接 false
POST 请求 body 怎么塞进 stream_context_create
HTTP POST 不是靠 post 键,而是用 content + method 组合。body 数据要自己序列化,context 不会帮你 urlencode 或 JSON 编码。
$data = http_build_query(['name' => '张三', 'age' => 25]);
$ctx = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
'content' => $data,
'timeout' => 8,
]
]);
$result = file_get_contents('https://api.example.com/login', false, $ctx);
- 如果发 JSON,
content直接填json_encode($arr),同时把Content-Type改成application/json -
Content-Length必须显式写,否则某些服务端(尤其是 Nginx + PHP-FPM)会收不到 body - 别用
curl思维去设post_fields——stream_context_create没这参数,写了就丢弃
HTTPS 请求证书验证失败咋办
默认情况下,PHP 7.0+ 的 https 流会校验 SSL 证书。报错 SSL operation failed with code 1 或 unable to verify the first certificate,基本就是证书问题。
立即学习“PHP免费学习笔记(深入)”;
临时调试可关验证,但生产环境禁止这么干:
$ctx = stream_context_create([
'http' => [...],
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
]
]);
- 真正解决应配
cafile,指向系统或自定义 CA 包:'cafile' => '/etc/ssl/certs/ca-certificates.crt' -
verify_peer和verify_peer_name要一起关,只关一个可能仍失败 - 某些内网 HTTPS 服务用私有 CA,得把对应 root cert 追加到 cafile,不能只靠
allow_self_signed
file_get_contents 用 context 时容易漏的坑
file_get_contents 第二个参数是 $use_include_path,第三个才是 $context。很多人传错位置,导致 context 完全没生效。
- 调用必须是:
file_get_contents($url, false, $ctx),中间那个false不能省或写成null - 如果 URL 是本地文件路径(如
./data.txt),http选项完全无效——context 只对网络流起作用 - 出错时
file_get_contents返回false,但不会抛异常,记得用error_get_last()看底层 socket 错误
context 看似简单,但每个键的位置、大小写、换行符、单位、协议层级都卡得死。写完最好用 var_dump(stream_context_get_options($ctx)) 对照一眼,比猜强。











