PHP 7.2升级后file_get_contents获取API JSON失败的原因与解决方法
问题原因与修复方案
我之前也碰到过类似的情况,PHP 7.2在HTTP请求处理上做了不少安全相关的调整,你遇到的这个问题核心原因是:PHP 7.2开始默认不再支持在URL中直接嵌入HTTP基本认证的用户名和密码(也就是https://username:password@domain这种格式)。官方调整这个行为,是因为明文把凭据放在URL里很容易被日志记录、泄露,存在不小的安全风险。
下面给你几个可行的修复方案,按推荐程度排序:
方案1:用流上下文传递认证信息(最推荐)
这是PHP 7.2+官方推荐的安全做法,把认证信息通过stream_context_create创建的请求上下文传递,而不是直接写在URL里。代码示例如下:
// 先移除URL里的认证信息,只保留地址和参数(注意给参数做urlencode处理,避免特殊字符破坏格式) $url = 'https://project_domain/api/json/xxx/?param_a=' . urlencode($a) . '¶m_b='. urlencode($b); // 生成HTTP Basic认证的头部内容 $authHeader = "Authorization: Basic " . base64_encode("你的用户名:你的密码"); // 创建包含认证信息的请求上下文 $context = stream_context_create([ 'http' => [ 'header' => $authHeader, 'timeout' => 10 // 可选,设置超时时间避免请求卡住 ] ]); // 发起请求 $result = file_get_contents($url, false, $context); // 如果还是失败,打印错误信息排查问题 if ($result === false) { var_dump(error_get_last()); }
方案2:临时启用URL认证解析(不推荐)
如果你暂时不想调整代码结构,可以通过配置让PHP重新支持解析URL中的认证信息,但这种方式安全隐患依然存在,绝对不建议在生产环境使用:
// 在代码开头添加这两行,临时修改流上下文的默认配置 ini_set('user_agent', 'PHP'); stream_context_set_default([ 'http' => [ 'follow_location' => true, 'user_agent' => 'PHP' ] ]); // 之后再调用原来的file_get_contents即可 $result = file_get_contents($url);
也可以修改php.ini文件,把user_agent设置为非空值(比如PHP),但这种全局配置影响范围大,同样不推荐。
额外排查点
如果上面的方法都没解决问题,建议你打印error_get_last()查看具体错误信息,针对性处理:
- 如果是SSL相关错误:可能是目标服务器的证书不被PHP信任,可临时关闭SSL验证(生产环境禁止):
$context = stream_context_create([ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false ] ]); - 如果是连接超时:检查
php.ini里的default_socket_timeout配置,或者在请求上下文里设置timeout参数。
内容的提问来源于stack exchange,提问作者Anndexi9
相关产品推荐
相关产品推荐

