如何在php中利用旋度下载指定大小的文件

  介绍

本篇文章为大家展示了如何在php中利用旋度下载指定大小的文件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

php中使用基于libcurl的旋度函数,可以对目标url发起http请求并获取返回的响应内容。通常的请求方式类似如下的代码:

public  function  callFunction ($ url, postData美元,美元的方法,,头=& # 39;& # 39;)   {   时间=美元才能maxRetryTimes  3;   时间=美元才能curl  curl_init ();   ,,/* * * * * *初始化请求参数开始* * * * * */美元如果才能(strtoupper(方法),!==,& # 39;得到,,,,,postData美元){   ,,,curl_setopt (CURLOPT_POSTFIELDS,卷发,美元,json_encode (postData美元));   }才能elseif  (strtoupper(方法),===,& # 39;得到,,,,,postData美元){   ,,,url 美元。=,& # 39;? & # 39;只http_build_query ($ postData);   ,,}   ,,/* * * * * *初始化请求参数* * * * * */结束   curl_setopt_array才能(卷、美元,阵列(   ,,,CURLOPT_URL =祝辞,url,美元   ,,,CURLOPT_TIMEOUT =祝辞,10日   ,,,CURLOPT_NOBODY =祝辞,0,   ,,,CURLOPT_RETURNTRANSFER =祝辞;1   )才能);   如果才能(method ==, & # 39;文章# 39;){   ,,,curl_setopt(卷、美元,CURLOPT_POST,,真的);   ,,}   如果才能(false ==,空()){   ,,,curl_setopt (CURLOPT_HTTPHEADER,卷发,美元,美元头);   ,,}   时间=美元才能response 假;   而才能(($ response ===, false),,,, (——maxRetryTimes 美元;祝辞,0)){   ,,,response 美元;=,修剪(curl_exec旋度($));   ,,}   return 才能;$反应;   }

上面代码中的这个响应是卷发发美元起的这次http请求从$ url获取到的数据,如果没有在头中美元通过范围来指定要下载的大小,无论这个资源多大,那么都要请求完整的并返回的是这个URI的完整内容。通常只用curl来请求求一些接口或者远程调用一个函数获取数据,,所以这个场景下CURLOPT_TIMEOUT这个参数很重要。

对于旋度的使用场景不止访问数据接口,还要对任意的url资源进行检测是否能提供正确的http服务。当用户填入的url是一个资源文件时,例如一个pdf或者ppt之类的,这时候如果网络状况较差的情况下用旋度请求较大的资源,将不可避免的出现超时或者耗费更多的网络资源。之前的策略是完全下载(旋度会下载存储在内存中),请求完后检查内容大小,当超过目标值就把这个监控的任务暂停。这样事发后限制其实治标不治本,终于客户提出了新的需求,不能停止任务只下载指定大小的文件并返回md5值由客户去校验正确性。

经过了一些尝试,解决了这个问题,记录过程如下文。

<强> 1,尝试使用CURLOPT_MAXFILESIZE。

对php和libcurl的版本有版本要求,完全的事前处理,当发现目标大于设置时,直接返回了超过大小限制的错误而不去下载目标了,不符合要求。

<强> 2,使用旋度下载过程的回调函数。

参考http://php.net/manual/en/function.curl-setopt-array.php,最终使用了CURLOPT_WRITEFUNCTION参数设置了on_curl_write,该函数将会1 s中被回调1次。

ch 美元;=,curl_init ();   options 美元;=,阵列(CURLOPT_URL ,,,=祝辞,& # 39;http://www.php.net/& # 39;,   CURLOPT_HEADER ,,,=祝辞,假的,   CURLOPT_HEADERFUNCTION ,=祝辞,& # 39;on_curl_header& # 39;   CURLOPT_WRITEFUNCTION ,=祝辞,& # 39;on_curl_write& # 39;   );

最终我的实现片段:

function  on_curl_write (ch美元,,数据)   {   时间=美元才能pid  getmypid ();   时间=美元才能downloadSizeRecorder  DownloadSizeRecorder: getInstance ($ pid);   时间=美元才能bytes  strlen(元数据);   美元才能downloadSizeRecorder→downloadData 。=,元数据;   美元才能downloadSizeRecorder→downloadedFileSize  +=,美元字节;//,,error_log (& # 39;, on_curl_write  & # 39;。美元downloadSizeRecorder→downloadedFileSize干净,祝辞,{downloadSizeRecorder→美元最大容量},\ n",, 3,, & # 39;/tmp/hyb.log& # 39;);//才能确保已经下载的内容略大于最大限制   if 才能;(($ downloadSizeRecorder→downloadedFileSize 作用;美元字节),祝辞,downloadSizeRecorder→美元最大尺寸),{   ,,,return 假;   ,,}   return 才能;美元字节,//这个不正确的返回,将会报错,中断下载,“errno": 23日,“errmsg":“Failed  writing  body  (0, !=, 16384),   }

DownloadSizeRecorder是一个单例模式的类,旋度下载时记录大小,实现返回下载内容的md5等。

如何在php中利用旋度下载指定大小的文件