curl的速度为什么比file_get_contents快以及具体原因

举报
lxw1844912514 发表于 2022/03/27 01:12:52 2022/03/27
【摘要】 一、背景      大家做项目的时候,不免会看到前辈的代码。博主最近看到前辈有的时候请求外部接口用的是file_get_contents,有的用的是curl。稍微了解这两部分的同学都知道,curl在性能上和速度上是优于file_get_contents的,那么为什么呢,从...

一、背景
      大家做项目的时候,不免会看到前辈的代码。博主最近看到前辈有的时候请求外部接口用的是file_get_contents,有的用的是curl。稍微了解这两部分的同学都知道,curl在性能上和速度上是优于file_get_contents的,那么为什么呢,从哪里体现出来的差距呢?

二、file_get_contents和curl
1、file_get_contents概述

file_get_contents() 函数把整个文件读入一个字符串中。
手册:http://www.w3school.com.cn/php/func_filesystem_file_get_contents.asp

      这里可以看出来,file_get_contents函数的最优选择是读取文件的内容。要求对方的服务器php.ini必须开启:allow_url_fopen

2、curl的概述

      CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。需要php.ini开启curl扩展

参考文章:http://www.cnblogs.com/manongxiaobing/p/4698990.html

      从定义上来说,curl作为一个开源库,拥有众多的语法也支持众多的协议,这点能看出来curl相比于file_get_contents() 是能做更多的事情的

三、为什么curl比file_get_contents好
博主百度了网上的众多说法,总共分为下面几个方面:

1、file_get_contents() 更容易造成服务器挂掉

关于造成服务器挂掉,这部分主要涉及两个方面:

(1)直接使用file_get_contents,未设置超时处理造成nginx报错:502 Bad Gateway

这部分大家可以参考博客:http://www.cnblogs.com/aipiaoborensheng/p/5000096.html

      设置超时时间即可。当然,如果是选用curl的话,设置超时时间会更加的方便,明显,一般不会因为超时而造成服务器垮掉。

(2)用file_get_contents请求效率很低,页面经常卡顿很久

      这部分在网上也有个解释,说file_get_contents每次请求远程URL中的数据都会重新做DNS查询,并不对DNS信息进行缓存。而curl则可以通过设置参数的方式来缓存DNS,从而达到快速访问的目的

curl设置DNS缓存:


    
  1. CURLOPT_DNS_USE_GLOBAL_CACHE 启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认启用。
  2. CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,默认为120秒。

参考链接:https://www.cnblogs.com/jking10/p/6595981.html

(3)curl能做到file_get_contents做不到的事情

      这部分是博主之前解决一个需求的时候发现的。当我需要把网络图片转换为二进制的图片流的时候,curl能实现,而file_get_contens就不行。

参考我之前的文章:https://blog.csdn.net/LJFPHP/article/details/81357839

2、file_get_contents速度很慢

      关于速度慢的原因,一部分是DNS缓存,这确实是file_get_contents的瓶颈,另一方面就是关于header头的原因。大家都知道,file_get_contents的请求是不带头的,这样它接收完所有数据后,没有主动断开和服务器的http连接。

解决方案:


    
  1. $opts = array(
  2. 'http'=>array(
  3. 'method' => 'POST',
  4. 'header' => 'Content-type:application/x-www-form-urlencoded',
  5. 'content' => $postdata,
  6. 'timeout' => 60 * 10 // 超时时间(单位:s)
  7. 'Connection'=>"close"
  8. )
  9. );
  10. $context = stream_context_create($opts);
  11. file_get_contents($filename, false, $context);

      我们通过设置句柄的方式,定义超时时间和header头,这样就能最大化的提升file_get_contents的速度

3、file_get_contents请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。

      这部分博主查询了下keeplive的相关知识,发现自己对于http请求方面还不是很熟悉。关于keeplive也是一个很大模块,博主这里就也不废话了,给大家推荐几篇不错的博客,有兴趣的可以看看:

1)(apache)http的keeplive

https://blog.csdn.net/jackyrongvip/article/details/9217931
http://www.cnblogs.com/hixiaowei/p/9261358.html

(2)tcp的keepAlive

http://www.cnblogs.com/xiaoleiel/p/8308514.html

四、关于服务器是否支持file_get_contents的判断方法
      众所周知的,file_get_contents是需要请求的服务商开启allow_url_fopen,但是很多服务商为了安全考虑都会关掉这个功能。而curl是要求php必须开启curl扩展。不过相对来说,很少有服务商不开启curl的,所以curl的运用场合会更多一些。

这里我们可以使用php自带的:function_exists方法来判断服务商是否定义的有此方法。
文档:http://php.net/manual/zh/function.function-exists.php
代码:


    
  1. if(function_exists('file_get_contents')) {
  2. $file_contents = file_get_contents($url);
  3. } else {
  4. //这里可以执行curl方案
  5. }

      通过对比我们也能发现两个函数的优劣势。如果是读取文件或者只是去拉取数据,那么file_get_contents的效率比较高 也比较简单。如果是要进行远程连接或者高频次的访问,那么还是老老实实用curl吧。

end
---------------------
版权声明:本文为CSDN博主「铁柱同学」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LJFPHP/article/details/83822628

文章来源: blog.csdn.net,作者:lxw1844912514,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/lxw1844912514/article/details/100028042

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。