在进行网络资源抓取时,最常用的方法有,curl和file_get_contents以及file。如果不考虑代码性能,三者功能类似。但也存在区别:
1.file_get_contents 每次请求都会重新做DNS查询,并不对DNS信息进行缓存。但CURL会自动缓存DNS信息。对同一域名下的网页或者图片请求只需一次DNS查询。大大减少了DNS查询的次数。所以CURL的性能优于file_get_contents。
2.file_get_contents 在请求HTTP时,使用的是http_fopen_wrapper,不会keep_live。但curl可以。这样在多次请求多个链接时,curl效率更高。
3.file_get_contents 函数会受到php.ini文件中allow_url_open选项配置的影响。如果配置关闭,则该函数也就会失效。而curl不受该配置的影响。
;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;;
; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-fopen
allow_url_fopen=On
但是curl会收到php.ini文件中模块加载的影响。如果关闭了,也会失效。
extension=php_curl.dll
4.curl 可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而file_get_contents只能使用get方式获取数据。
另外:与之类似的一个函数file,file_get_contents 获取远程文件时会把结果都存在一个字符串中,files是将整个文件读入一个数组中。
适用场景:
1.file_get_contents一般用于本地文件或者读取频次很低的操作,而curl则常用于网络大文件的读取,而且curl在稳定性、服务器负载和功能方面都要优于另外两个函数。
2.对于网络资源小文件而言,curl速度慢于另外两个函数,而file_get_contents优于file。
以http://www.google.cn为例,速度如下:
0.36021900177002 (curl)
0.29601693153381 (file_get_contents)
0.33401894569397 (file)
以http://www.sina.com.cn为例,速度如下:
0.23661303520203 (curl)
0.7730438709259 (file_get_contents)
0.95105504989624 (file)
说明curl的优越性。但是,对于内容量比较大的资源,后两者会出现如下错误:
Fatal error: Maximum execution time of 30 seconds exceeded
显然,后两者在php.ini设置的时间限制内,无法读取资源内容,报了个超时的错误,稳定性较差。
综上所述:curl在速度、稳定性等方面优于file_get_contents和file。建议在实际应用中更多的采用curl方法。
下面附上测试源代码:
<?php
function getBycurl($url){
$ch=curl_init();
$timeout=5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$lines_string=curl_exec($ch);
curl_close($ch);
//echo htmlspecialchars($lines_string);
}
function getByfgc($url){
$contents=file_get_contents($url);
//echo htmlspecialchars($contents);
}
function getByfile($url){
$lines_array=file($url);
$lines_string=implode('',$lines_array);
//echo htmlspecialchars($lines_string);
}
$url="http://www.sina.com.cn";
$stime=microtime(true);
getBycurl($url);
$etime=microtime(true);
$time=$etime-$stime;
echo $time."<br/>";
$stime1=microtime(true);
getByfgc($url);
$etime1=microtime(true);
$time1=$etime1-$stime1;
echo $time1."<br/>";
$stime2=microtime(true);
getByfile($url);
$etime2=microtime(true);
$time2=$etime2-$stime2;
echo $time2;
?>