功能:1.将文件压缩下载 2.控制下载的速度 3. 实时提现下载速度
效果图:
代码如下:
<?php
// argv 0=> 脚本的相对路径 1=>第一参数
// 请求参数php urlstream.php http://127.0.0.1/example/temp.log
if($argc <2){
echo 'incomplete request parameters';die;
}
// 获取URL
$url = $argv[1];
// 宽带限制
if($argc == 3){
$max_kb_sec = $argv[2];
}else{
$max_kb_sec = 10; // 单位kb/s
}
$severity_map = array(
0=>'info',
1=>'warning',
2=>'error'
);
$timer = 0;
//指向流事件的回调函数
function notifier($code,$severity ,$msg,$xcode,$sofar,$max){
global $term_sol,$severity_map,$max_kb_sec,$size,$timer;
//当接收到PROGRESS事件时,不打印状态信息前缀
if($code != STREAM_NOTIFY_PROGRESS){
echo $severity_map[$severity].":";
}
switch ($code){
// 链接资源后触发
case STREAM_NOTIFY_CONNECT:
print ("connected\n");
$GLOBALS['begin_time'] = time()-0.001;
break;
// 当一个认证的请求完成,这个事件通过流的API触发
case STREAM_NOTIFY_AUTH_REQUIRED:
printf("authentication required:%s\n",trim($msg));
break;
// 告诉你是否成功认证或链接失败
case STREAM_NOTIFY_AUTH_RESULT:
printf("Logged in :%s\n",trim($msg));
// http处理层在请求的响应中获得content-type头信息时触发
case STREAM_NOTIFY_MIME_TYPE_IS:
printf("Mime type:%s\n",$msg);
break;
// 当FTP层计算出文件的大小时触发或HTTP层看到content-length头信息触发
case STREAM_NOTIFY_FILE_SIZE_IS:
printf("Downloading %d kb\n",$max/1024);
// 设置全局的宽度变量
$size = $max;
break;
// HTTP处理层遇到重定向请求(location:header)时触发
case STREAM_NOTIFY_REDIRECTED:
printf("Redirecting to %s..\n",$msg);
break;
// 在数据包到达后迅速发送,在这个例子中我们执行贷款限制和进度条的显示
case STREAM_NOTIFY_PROGRESS:
// 计算星星标记和条纹数
if($size){
$stars = str_repeat('*',$c=$sofar/$size*50);
}else{
$stars = '';
}
$stripe = str_repeat('-',50-strlen($stars));
//用kb/sec的单位计算下载速度
$kb_sec = ($sofar / (time() - $GLOBALS['begin_time']))/1024;
//echo "raw speed:".$kb_sec."__".$max_kb_sec."\n"; 查看原始速度
// 如果超过了最高的输出速度,停止脚本
while($kb_sec>$max_kb_sec) {
usleep(1);
$kb_sec = ($sofar/(time()-$GLOBALS['begin_time']))/1024;
}
//echo "current speed:".$kb_sec."__".$max_kb_sec."\n";查看限制后的速度
//显示进度条
$timer++;
printf("[%s]%d kb %.lf kb/sec\n\n",$stars.$stripe,$sofar/1024,$kb_sec);
break;
// 显示错误信息,例如签名错误
case STREAM_NOTIFY_FAILURE:
printf("Failure:%s\n",$msg);
break;
}
}
// 同时确定保存的文件名
$url_data = parse_url($argv[1]); // 拆分路径
$file = basename($url_data['path']);
if(empty($file)){
$file = 'form.html';
}
printf("saving to $file.gz\n");
$fil = "compress.zlib://$file.gz";
//创建上下文并且设置notifier的回调函数
$context = stream_context_create();
stream_context_set_params($context,array("notification"=>"notifier"));
//打开目标文件
$fp = fopen($url,"rb",false,$context);
if(is_resource($fp)){
// 打开本地文件
$fs = fopen($fil,"wb",false,$context);
if(is_resource($fs)){
// 从URL以每块1024字节来读取数据
$i = 0;
while(!feof($fp)){
$data = fgets($fp,1024);
fwrite($fs,$data);
}
// 关闭远程文件
fclose($fs);
}
fclose($fp);
printf("[%s] Download time:%ds\n",str_repeat('*',50),time()-$GLOBALS['begin_time']);
}