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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Javascript的DOM操作

    Javascript的DOM操作

    2021年11月17日
  • 五分钟JAVA代码教会你:FFmpeg实现视频试看(window版本)「建议收藏」

    当领导要你开发视频试看功能,怎么破??我用JAVA代码教会你,花5分钟就能学会,赶紧来看看吧。

  • data grip 激活码-激活码分享2022.02.20

    (data grip 激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~HC…

  • java里的全局变量_全局变量的值会不会改变

    java里的全局变量_全局变量的值会不会改变在类定义(声明)了全局变量,没有对其赋值,利用类内的方法对其赋值,其值变成了方法给的值,无论是在方法内部还是方法外。(除非你定义了同名的局部变量)

  • 小树剪发网1114_aow把抓

    小树剪发网1114_aow把抓乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过 50 个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。输入格式输入包含多组数据,每组数据包括两行。第一行是一个不超过 64 的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。输出格式为每组数据,分别输出原始木棒的可能最小长度

  • 三星识别文字_免费文字识别

    三星识别文字_免费文字识别百度AI实战营收官战(成都站),宣告百度OCR免费策略再次升级。百度通用文字识别服务的免费使用次数提升100倍,从每天500次提升至每天50000次;通用文字识别高精度版的免费使用次数提升10倍,从每天50次提升至每天500次。目前业界通常按照接口调用次数收费,单个接口单次调用费从几分钱到几毛钱不等,百度永久免费开放通用文字识别及其他文字识别技术,实实在在为企业节约一笔不菲的支出。现阶段已…

发表回复

您的电子邮箱地址不会被公开。

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