页面突然报 file_get_contents(): https:// wrapper is disabled in the server configuration,换个地址又提示 failed to open stream: HTTP request failed! 这类错误看着吓人,其实多数就卡在两三个配置上,先看报错里的关键词,比盲目改代码快。
先确认 allow_url_fopen 开没开
file_get_contents 既能读本地文件,也能读 URL,但读 URL 要求 php.ini 里 allow_url_fopen=On。改完记得重启 PHP-FPM 或 Apache,用 phpinfo() 看一眼实际生效的值,别只改了一个不存在的 ini。用 php --ini 也能确认当前加载的是哪个配置文件。
如果主机商关掉了这个选项,改用 cURL 扩展,功能更全,也能自己设请求头。共享主机常见的坑是本地测试正常,传上去就报错,多半就是这一项被关了。
被挡 403 就补请求头和超时
很多站点会拒绝没有 User-Agent 的请求。用 stream_context_create 传一个上下文,把 UA 和超时写上,再传给第三个参数:
$opts = ['http' => ['header' => 'User-Agent: Mozilla/5.0', 'timeout' => 5]]; $ctx = stream_context_create($opts); $html = file_get_contents($url, false, $ctx);返回值是 false 时别急着往下跑,先 var_dump($http_response_header) 看状态码。默认的 default_socket_timeout 是 60 秒,线上抓取建议压到 5 到 10 秒。302 跳转默认会跟着走,跨域跳几次就可能超时。
大文件和并发别用它
它会把整个响应读进内存,几百 MB 的日志或视频很容易把内存打满。这种情况用 fopen 配合 fread 分块读,或者干脆上 cURL。读大文件时还可以用 stream_copy_to_stream 直接写到本地文件。
需要 POST 时也能做,在上下文里写 method 和 content,content 用 http_build_query 拼。简单的 GET 抓取,它一行就够。要重试、并发、限速,还是 cURL 稳。抓公开页面注意频率,别把对方站点拖垮,这比技术选型更重要。