PHP中使用file_get_contents下载图片缓慢的原因和解决办法

通过什么方式下载快?

前几天修改一个项目,要将微信头像本地化。
于是写了个脚本,使用了最简便的函数file_get_contents。
代码如下:

但不久就发现问题了,下载时候巨慢,同样的图片地址,用浏览器打开就非常快,可以排除是网络问题。

后来尝试使用curl下载,虽然代码多了几行,但速度和浏览器打开的速度一样快。
代码如下:

为什么有时候cURL比file_get_contents快?

起初以为是http请求头的问题,于是开始使用Wireshark抓包。
各种情况罗列如下:

用file_get_contents访问百度首页,请求没有延迟:

用file_get_contents访问微信头像,请求有延迟:

用Wireshark查看,请求发出后,立即捕获到了响应的http,但php脚本在一直卡着,

用curl访问百度首页,请求没有延迟:

用curl访问微信头像,请求没有延迟:

罗列了这么多,貌似一眼也看不出问题在哪。
经过查阅,发现是HTTP响应头中的Connection: Close决定了file_get_contents是否有延迟。

若要刨根问底,可能要去研究PHP源码和HTTP协议了,学无止境!

一网友评论"PHP中使用file_get_contents下载图片缓慢的原因和解决办法"

  1. 这个问题出现的原因是,服务器强制配置成http 1.1导致的。解决的办法是$data = file_get_contents('http://www.example.com/', null, stream_context_create([
    'http' => [
    'protocol_version' => 1.1,
    'header' => [
    'Connection: close',
    ],
    ],
    ]));

    参考:

    Note that if you set the protocol_version option to 1.1 and the server you are requesting from is configured to use keep-alive connections, the function (fopen, file_get_contents, etc.) will "be slow" and take a long time to complete. This is a feature of the HTTP 1.1 protocol you are unlikely to use with stream contexts in PHP.

    Simply add a "Connection: close" header to the request to eliminate the keep-alive timeout:

    [
    'protocol_version' => 1.1,
    'header' => [
    'Connection: close',
    ],
    ],
    ]));
    ?>

发表评论

电子邮件地址不会被公开。 必填项已用*标注