zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    睁大你的眼睛,警惕职业生涯中的“红灯”
    几则好玩的脑筋急转弯
    File.Delete()的解决
    Powershell之True或False
    发送邮件
    IE与CSS兼容性
    WSS
    File.Delete()
    添加field部署
    css加载
  • 原文地址:https://www.cnblogs.com/lxwphp/p/11352191.html
Copyright © 2011-2022 走看看