<?php
class Download {
/**
* 请求超时时间,单位秒
* @var int
*/
public $_timeout = 20;
/**
* 设置保存路径
* note:路径最后以 “/” 结束
* @var string
*/
private $_savePath = './';
/**
* 设置超时时间
* @param int $second 单位秒
*/
public function setTimeout($second) {
$this->_timeout = intval($second);
}
/**
* 设置保存路径
* @param $path
*/
public function setSavePath($path) {
$this->_savePath = $path;
}
/**
* curl批量下载文件
* @param array $urls 下载链接
* @param string $callback 回调函数
* @return array
*/
public function multiDown(array $urls,$callback)
{
if (empty($urls)) {
return array();
}
$urlsMap = array(); //保存curl句柄与url的关联
$chs = curl_multi_init();
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //请求地址
curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout); //请求超时时间,如果下载文件比较大,建议将值设置大一点
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //设置为1,表示页面不直接输出返回数据
curl_setopt($ch, CURLOPT_NOSIGNAL, true); //设置超时,需要设置这一项
curl_setopt($ch, CURLOPT_HEADER, 0); //不显示头部信息
curl_multi_add_handle($chs,$ch);
$urlsMap[strval($ch)] = $url;
}
$active = null;
$response = array(); //初始化函数返回值
do {
if (curl_multi_exec($chs,$active) == CURLE_OK) {
while ($done = curl_multi_info_read($chs)) {
$url = $urlsMap[strval($done['handle'])];
$args = $this->_getCurlDetail($done['handle'],$url);
if ($callback && method_exists($this,$callback)) {
$this->$callback($args);
}
$response[$url] = $args;
curl_multi_remove_handle($chs,$done['handle']);
curl_close($done['handle']);
}
}
} while ($active > 0);
curl_multi_close($chs);
return $response;
}
/**
* 获取curl信息(错误,信息,内容,请求url)
* @param $ch curl句柄
* @param $url
* @return array
*/
private function _getCurlDetail($ch,$url)
{
$args = array();
if (empty($ch)) {
return $args;
}
$args['error'] = curl_error($ch);
$args['info'] = curl_getinfo($ch);
$args['result'] = curl_multi_getcontent($ch);
$args['url'] = $url;
return $args;
}
/**
* 处理curl返回数据
* @param $args
*/
private function _dealData($args)
{
if (empty($args['error'])) {
if ($args['info']['http_code'] == '200') {
$color = 'green';
file_put_contents($this->_getFilename($args['url']),$args['result']);
} else {
$color = 'orange';
}
$content = $args['url'].' -- '.$args['info']['http_code'];
} else {
$color = 'red';
$content = $args['url'].' -- '.$args['error'];
}
$this->_showHtml($content,$args['url'],$color);
}
/**
* 格式化显示内容
* @param $content
* @param $url
* @param $color
*/
private function _showHtml($content,$url,$color)
{
echo '<li>';
echo '<a href="'.$url.'" style="color: '.$color.'">'.$content.'</a>';
echo '</li>';
}
/**
* 根据url生成文件名
* note:该方法需要根据实际url情况重写,这里的方法并不完善
* @param $url
* @param string $ext 文件后缀名,默认为zip
* @param bool $isRename 是否重新命名
* @return string
*/
private function _getFilename($url,$ext = '.zip',$isRename = true)
{
if ($filename = strrchr($url,'/')) {
if (strpos($filename,'.') === false) {
$filename = rand(1,99999).$ext;
}
}
$filename = $this->_savePath.$filename;
if (file_exists($filename) && $isRename) {
$filename .= rand(1,9999);
}
return $filename;
}
}
//使用方法
$download = new Download();
//下载队列
$urls = array(
'https://img-my.csdn.net/uploads/201212/28/1356680367_3703.jpg',
'http://newtab.firefoxchina.cn/img/sitenav/logo.png',
);
$download->setTimeout(10);
$download->setSavePath('./');
$result = $download->multiDown($urls,'_dealData');
//var_dump($result);
参考博客:http://www.eer3.com/article/artdetails/40.htm