>  기사  >  백엔드 개발  >  php如何实现长时间下载不中断,急!急!急!

php如何实现长时间下载不中断,急!急!急!

WBOY
WBOY원래의
2016-06-23 14:19:221114검색

php长时间下载不中断

求一个php长时间循环下载网站api文件不中断的方法
或者求一个可以每天下载相同任务的软件,然后放在计划任务里面可用的
主要用来下载api文件
目前我是用php的copy函数下载,下1个多小时后就下载不了了,不知道什么原因,是不是还要设置什么东东啊???
求大神帮忙~~~~~

回复讨论(解决方案)

首先,如果你要抓10W条数据  建议你不要一次全抓

抓1000条,看看执行时间,如果是1分钟,你可以写一条命令(linux)或者计划任务(windows)每隔3分钟执行一次

如果一次执行就10W条 那肯定容易出问题

<?phpheader("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'ftp://IP:端口/'.date("Ymd",time()).'.sql';curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = 'D:/backup/';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.sql',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
学CURL的时候写的一个下载服务器上备份数据库的小程序。添加个计划任务访问这个页面实现下载。

首先,如果你要抓10W条数据  建议你不要一次全抓

抓1000条,看看执行时间,如果是1分钟,你可以写一条命令(linux)或者计划任务(windows)每隔3分钟执行一次

如果一次执行就10W条 那肯定容易出问题

您好,谢谢您的解答
说明下,下载的单个文件不是很大,只有几兆-30兆之间
主要是文件有600多个,导致长时间下载程序中断了
之前是有做个数据库来保存下载记录用于判断,但是是分多次执行完成的
有没有什么方法,可以一次性执行完成
或者有什么软件可以实现这样的功能


首先,如果你要抓10W条数据  建议你不要一次全抓

抓1000条,看看执行时间,如果是1分钟,你可以写一条命令(linux)或者计划任务(windows)每隔3分钟执行一次

如果一次执行就10W条 那肯定容易出问题

您好,谢谢您的解答
说明下,下载的单个文件不是很大,只有几兆-30兆之间
主要是文件有600多个,导致长时间下载程序中断了
之前是有做个数据库来保存下载记录用于判断,但是是分多次执行完成的
有没有什么方法,可以一次性执行完成
或者有什么软件可以实现这样的功能


很抱歉我还没听说过有这样的软件...   很多码农和我一样在面对复杂需求的死后喜欢自己写个代码来跑....

就用你的方法不是挺好么  用数据库保存下下载记录,每次下载固定个数,下次执行时从未记录处开始继续下载,然后跑计划任务或者wget即可

也许你需要 set_time_limit(0);?

<?phpheader("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'ftp://IP:端口/'.date("Ymd",time()).'.sql';curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = 'D:/backup/';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.sql',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
学CURL的时候写的一个下载服务器上备份数据库的小程序。添加个计划任务访问这个页面实现下载。
您好,谢谢您的解答
我下载的是别人服务器上的api文件没ftp
刚用您的程序试了下,好像不能下载,不知道是不是我改的有错,您帮忙看下
header("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'http://www.meituan.com/api/v2/changle/deals';//这样的文件有600多个curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = '';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.xml',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}

也许你需要 set_time_limit(0);?
您好,这个我有用,但还是运行到1个多小时程序就断了,请问下还需要设置什么吗?


<?phpheader("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'ftp://IP:端口/'.date("Ymd",time()).'.sql';curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = 'D:/backup/';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.sql',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
学CURL的时候写的一个下载服务器上备份数据库的小程序。添加个计划任务访问这个页面实现下载。
您好,谢谢您的解答
我下载的是别人服务器上的api文件没ftp
刚用您的程序试了下,好像不能下载,不知道是不是我改的有错,您帮忙看下
header("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'http://www.meituan.com/api/v2/changle/deals';//这样的文件有600多个curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = '';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.xml',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
用readdir遍历下目录,循环执行下载就行了,反正用set_time_limit(0);设置了脚本执行时间无限制,你所有文件估计有6G以上吧。


也许你需要 set_time_limit(0);?
您好,这个我有用,但还是运行到1个多小时程序就断了,请问下还需要设置什么吗?

我个人表示...很正常... PHP在处理长时间的程序上确实比较?,当然,必须强调的是这是个人看法,理论上在严苛的环境下能够顺利执行?(稳定的网络环境+足够巨大的内存

还是分开抓吧...


您好,因为下载完成后,还需要导入到数据库,但是我不知道什么时候才下载完,这个要用什么方式来做判断比较好呢?
还有一点,目前是在计划任务里面,添加批处理的方式打开程序,然后执行10秒后自动关闭掉进程,但是程序还是有执行下载1个多小时后才中断,这样对服务器会有什么影响吗?



<?phpheader("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'ftp://IP:端口/'.date("Ymd",time()).'.sql';curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = 'D:/backup/';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.sql',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
学CURL的时候写的一个下载服务器上备份数据库的小程序。添加个计划任务访问这个页面实现下载。
您好,谢谢您的解答
我下载的是别人服务器上的api文件没ftp
刚用您的程序试了下,好像不能下载,不知道是不是我改的有错,您帮忙看下
header("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'http://www.meituan.com/api/v2/changle/deals';//这样的文件有600多个curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = '';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.xml',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
用readdir遍历下目录,循环执行下载就行了,反正用set_time_limit(0);设置了脚本执行时间无限制,你所有文件估计有6G以上吧。
嗯,是的,差不多有5G左右


您好,因为下载完成后,还需要导入到数据库,但是我不知道什么时候才下载完,这个要用什么方式来做判断比较好呢?
还有一点,目前是在计划任务里面,添加批处理的方式打开程序,然后执行10秒后自动关闭掉进程,但是程序还是有执行下载1个多小时后才中断,这样对服务器会有什么影响吗?


这类问题不是具体的某个语句的问题,所以我只能说我的思路无法保证这样就一定能行或者是最好的

你可以copy之前和copy完完之后再数据库写两个开始/结束标志  

在php文件copy之前检查上一个程序是否执行完毕,如果没有就退出,如果有,就写上开始标志开始copy

这样根本不存在执行一个多小时的问题吧...



您好,因为下载完成后,还需要导入到数据库,但是我不知道什么时候才下载完,这个要用什么方式来做判断比较好呢?
还有一点,目前是在计划任务里面,添加批处理的方式打开程序,然后执行10秒后自动关闭掉进程,但是程序还是有执行下载1个多小时后才中断,这样对服务器会有什么影响吗?


这类问题不是具体的某个语句的问题,所以我只能说我的思路无法保证这样就一定能行或者是最好的

你可以copy之前和copy完完之后再数据库写两个开始/结束标志  

在php文件copy之前检查上一个程序是否执行完毕,如果没有就退出,如果有,就写上开始标志开始copy

这样根本不存在执行一个多小时的问题吧...

您好,执行一个小时是因为下载的文件数量太多了,因为我是循环下载的,下载到哪里停下,下次就从哪里再下载

好吧,我不知道如何让下载5G文件的PHP程序稳定执行好几个小时

刚才说的都是循环抓取的方案,如果要用一次抓取的,个人表示无法给出有效建议.

好吧,我不知道如何让下载5G文件的PHP程序稳定执行好几个小时

刚才说的都是循环抓取的方案,如果要用一次抓取的,个人表示无法给出有效建议.
您好,如果用wget的话可以实现一次性抓取吗?
因为我没用过wget,所以请教下

wget有断点续传功能 不过我没这样用过 可参阅

http://xinkang120.blog.163.com/blog/static/194668223201188114417360/

PHP断点下载,可以找相关插件。

如果是windows服务器,可以考虑cmd执行,这个是没有超时 时间,且不会掉线的。

上次用这个方法抓取了5000多个flash小游戏文件,挂在服务器执行即可。


另外:如果想尽快下载的话,可以考虑不用PHP,使用PHP把抓取到得待采集文件地址入库,导出成列表。导入到迅雷或者其他下载软件进行批量下载,话说这个方法也试过,还不错

如果是windows服务器,可以考虑cmd执行,这个是没有超时 时间,且不会掉线的。

上次用这个方法抓取了5000多个flash小游戏文件,挂在服务器执行即可。


另外:如果想尽快下载的话,可以考虑不用PHP,使用PHP把抓取到得待采集文件地址入库,导出成列表。导入到迅雷或者其他下载软件进行批量下载,话说这个方法也试过,还不错

您好,谢谢您的解答
第一种方法是用cmd执行php文件吗?如果是的话,我试过用cmd来处理网页也会超时的啊,不知道是不是我的方法不对,如果不是的话要怎么弄呢?
第二种用迅雷的话,要怎么做才能够每天都运行一次呢?因为我下载的链接是相同的,只是内容每天都有更新,但是迅雷下载完后好像不能重复下载,请教下这个要怎么设置?

看样子,你这种情况用迅雷是不行的,是一个计划任务。迅雷貌似没有提供什么接口给程序用。

用cmd的话,就是执行PHP文件,这里面没有超时的,即使php.ini配置了超时时间。比较简单的方法就是把PHP加入到系统Path里面(不晓得这个你会不会,不会的话google下),然后写一个bat文件就行了

php d:\wwwroot\cmd\task.phppause


这个task.php就是你用HTTP访问网页来执行任务的文件。把这个保存为.bat文件。双击执行即可,也可以加入到计划任务中,每天执行。

<?phpheader("content-type:text/html;charset=utf-8");set_time_limit(0);$curl = curl_init();$target_file = 'ftp://IP:端口/'.date("Ymd",time()).'.sql';curl_setopt($curl,CURLOPT_URL,$target_file);curl_setopt($curl, CURL_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_VERBOSE, 1);curl_setopt($curl, CURLOPT_FTP_USE_EPSV, 0);curl_setopt($curl,CURLOPT_TIMEOUT,300);curl_setopt($curl, CURLOPT_USERPWD, "update:windcms");$target_path = 'D:/backup/';if(is_dir($target_path)){	$outfile = fopen($target_path.'/'.date("Ymd",time()).'.sql',"w+");	curl_setopt($curl,CURLOPT_FILE,$outfile);	$info = curl_exec($curl);	fclose($outfile);	$error_no = curl_errno($curl);	if($error_no === 0){		echo "下载成功!";	}else{		echo "下载失败!";	}	curl_close($curl);}
学CURL的时候写的一个下载服务器上备份数据库的小程序。添加个计划任务访问这个页面实现下载。 此法可解

这种用shell来做不是更好啊

偶这边光纤也不敢保证很耗时的多文件下载能一次完成,我总是多次执行跳过已完成的确保全部下载完成
wget 或其他命令行客户端有检测跳过(或续传,续传一般建立在字节数固定的情况)的功能

如果想自动化,建议用log,记录仪下载完成的或出错的
循环N次,跳过完成的,重新下载出错的,直到log内记录全部都完成
或者log只记录出错的,循环下载直到log记录为0

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.