PHP 页面突然空白,日志里一行 Warning:file_get_contents(http://xxx): failed to open stream: HTTP request failed。昨天还好好的,今天接口就挂了。
它干的事很简单
这个函数把文件内容读成一个字符串,本地路径能用,开了 allow_url_fopen 之后,http 地址也能读。读配置、取模板,一行就够:$html = file_get_contents('config.json');远程接口同样写法,只是把路径换成网址。
远程请求要加超时和头
默认超时按 default_socket_timeout 走,常见是 60 秒,接口卡住时页面会一直转。用 stream context 传参更稳:
$opts = ['http' => ['method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => $body, 'timeout' => 5]]; $res = file_get_contents('https://example.com/api', false, stream_context_create($opts));返回 false 就说明失败了,别直接拿去做字符串操作。错误详情可以看 error_get_last,正式环境记得把 warning 写进日志,不要显示给用户。要发 POST,context 里的 method 和 content 必须成对写,少了 content 就是空请求。
大文件别用它硬读
这个函数会把整个文件塞进内存,几百 MB 的视频一次读进来,很容易触发 memory_limit 报错。大文件用 fopen 配合 fread 分块读,或者用 SplFileObject 按行处理。下载文件、走代理、处理证书,curl 更合适,超时和重定向都能细调。
安全上的两个提醒
路径不要直接拼用户输入,否则 ../ 就能读到系统文件。远程地址最好写死或者走白名单,别让参数决定请求哪里。文件不存在、没有读权限、网址返回 404,这个函数都只给一句 failed to open stream,排查时先确认路径和权限,再看网络。
这种写法适合简单场景,请求多了、要并发,还是换 curl 或者 HTTP 客户端。