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

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缓存:

CURLOPT_DNS_USE_GLOBAL_CACHE 启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认启用。
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连接。

解决方案:

      $opts = array(
        'http'=>array(
         'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $postdata,
                'timeout' => 60 * 10 // 超时时间(单位:s)
         	 'Connection'=>"close"
        )
      );
      $context = stream_context_create($opts);
      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
代码:

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/112128.html原文链接:https://javaforall.net

(0)
上一篇 2022年2月10日 上午7:00
下一篇 2022年2月10日 上午8:00


相关推荐

  • CentOS 如何安装 Git

    CentOS 如何安装 Git前言一般想要安装某一款软件包的时候通常会去查看官方文档官网上对各个平台如何安装 git 进行了说明 https git scm com download linux 一般的平台通常都能通过命令的方式去安装 git 的各个版本 包括当前官方最新版本 但是红帽系列通过 yum 安装却无法安装最新版本 而且都是很旧的版本 这种版本对许多新的命令以及特性都不支持 所以官方推荐像 CentOS 通过下载 git 源码包的方式去安装 RHELandderiv

    2026年3月17日
    2
  • 算法高级(21)-如何通过IP地址进行定位?[通俗易懂]

    最近项目有一个用户地域分析的需求,现在知道ip字段,需要通过用户的ip查找归属地,我们这里将ip直接转换成对应城市的字符串。一、通过IP库二分查找ip库是从淘宝买的,csdn下载地址:【ip字段国内外均有】ip.txt是ip地址和归属地的规则数据,里面的数据是根据ip地址的十进制从高到低排序。 第一个字段是网段的起始IP地址,第二个字段是网段的结束IP地址, 第三个字段是网段的…

    2022年4月17日
    82
  • plsql直接连接远程数据库_plsql远程连接oracle

    plsql直接连接远程数据库_plsql远程连接oracle前言每次安装Oracle以后,都会出现使用plsql连接不上的问题!多次重启电脑、重装系统的磨人经历之后,终于做出这么一篇文章,希望能帮助广大技术人员减少一些时间,顺利进行连接。注:也可以用plsql连接远程数据库(只要有oracle的network\admin\tnsnames.ora就行)。首先下载64位oracle以及32位轻量级客户端(注意版本的对应,我用的是11g的oracl……

    2022年10月20日
    4
  • 干货精讲!java分布式事务框架

    干货精讲!java分布式事务框架事故背景公司最近安排了一波商品抢购活动 由于后台小哥操作失误最终导致活动效果差 被用户和代理商投诉了 经理让我带同事们一起复盘这次线上事故 什么原因造成的 抢购活动计划是零点准时开始 22 00 运营人员通过后台将商品上线 23 00 后台小哥已经将商品导入缓存中 提前预热抢购开始的瞬间流量非常大 按计划是通过 Redis 承担大部分用户查询请求 避免请求全部落在数据库上 如上图预期大部分请求会命中缓存 但是由于后台小哥预热缓存的时候将所有商品的缓存时间都设置为 2 小时过期 所有的商品在同一个时间点全

    2026年3月16日
    2
  • pycharm如何分段运行_pycharm只运行部分代码

    pycharm如何分段运行_pycharm只运行部分代码在最新版的pycharm中拥有类似jupyter的分段执行代码功能,其使用方法如下:1.在想要分段运行的段前一行(空白行)输入#%%2.选择Usescientificmode3.分段运行的结果补充知识:Pycharm分行或分块执行介绍Pycharm中其实也可以使用类似于Spyder和Jupyter中的分行或分块执行,主要可以使用两种方法。需要注意的是,下面两种方法的本质都是在控制台执行,要注意…

    2022年8月26日
    55
  • 数据标准化/归一化normalization

    数据标准化/归一化normalizationhttp://blog.csdn.net/pipisorry/article/details/52247379这里主要讲连续型特征归一化的常用方法。连续型特征还有一种处理方式是,先分桶/分箱(如等频/等距的分)[待写]进行离散化后再使用离散数据的处理方法。离散数据处理参考[数据预处理:独热编码(One-HotEncoding)]。基础知识参考:[均值、方差与协方差矩阵][…

    2022年6月23日
    28

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号