php 超大文件下载程序[http 缓存协商,Etag标记,断点续传]
<?php教程
002 $file_path = './download/download_cn.rar';
003
004 //使用方法
005 downFile($file_path);
006
007 // 服务器文件路径,下载文件名字(默认为服务器文件名),是否许可用户下载方式(默认可选),速度限制(默认自动),文件类型(默认所有)
008 function downFile($fileName, $fancyName = '', $forceDownload = true, $speedLimit = 0, $contentType = '') {
009 if (!is_readable($fileName))
010 {
011 header("HTTP/1.1 404 Not Found");
012 return false;
013 }
014
015 $fileStat = stat($fileName);
016 $lastModified = $fileStat['mtime'];
017
018 $md5 = md5($fileStat['mtime'] .'='. $fileStat['ino'] .'='. $fileStat['size']);
019 $etag = '"' . $md5 . '-' . crc32($md5) . '"';
020
021 header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModified) . ' GMT');
022 header("ETag: $etag");
023
024 if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified)
025 {
026 header("HTTP/1.1 304 Not Modified");
027 return true;
028 }
029
030 if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) < $lastModified)
031 {
032 header("HTTP/1.1 304 Not Modified");
033 return true;
034 }
035
036 if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag)
037 {
038 header("HTTP/1.1 304 Not Modified");
039 return true;
040 }
041
042 if ($fancyName == '')
043 {
044 $fancyName = basename($fileName);
045 }
046
047 if ($contentType == '')
048 {
049 $contentType = 'application/octet-stream';
050 }
051
052 $fileSize = $fileStat['size'];
053
054 $contentLength = $fileSize;
055 $isPartial = false;
056
057 if (isset($_SERVER['HTTP_RANGE']))
058 {
059 if (preg_match('/^bytes=(d*)-(d*)$/', $_SERVER['HTTP_RANGE'], $matches))
060 {
061 $startPos = $matches[1];
062 $endPos = $matches[2];
063
064 if ($startPos == '' && $endPos == '')
065 {
066 return false;
067 }
068
069 if ($startPos == '')
070 {
071 $startPos = $fileSize - $endPos;
072 $endPos = $fileSize - 1;
073 }
074 else if ($endPos == '')
075 {
076 $endPos = $fileSize - 1;
077 }
078
079 $startPos = $startPos < 0 ? 0 : $startPos;
080 $endPos = $endPos > $fileSize - 1 ? $fileSize - 1 : $endPos;
081
082 $length = $endPos - $startPos + 1;
083
084 if ($length < 0)
085 {
086 return false;
087 }
088
089 $contentLength = $length;
090 $isPartial = true;
091 }
092 }
093
094 // send headers
095 if ($isPartial)
096 {
097 header('HTTP/1.1 206 Partial Content');
098 header("Content-Range: bytes $startPos-$endPos/$fileSize");
099
100 }
101 else
102 {
103 header("HTTP/1.1 200 OK");
104 $startPos = 0;
105 $endPos = $contentLength - 1;
106 }
107
108 header('Pragma: cache');
109 header('Cache-Control: public, must-revalidate, max-age=0');
110 header('Accept-Ranges: bytes');
111 header('Content-type: ' . $contentType);
112 header('Content-Length: ' . $contentLength);
113
114 if ($forceDownload)
115 {
116 header('Content-Disposition: attachment; filename="' . rawurlencode($fancyName). '"');
117 }
118
119 header("Content-Transfer-Encoding: binary");
120
121 $bufferSize = 2048;
122
123 if ($speedLimit != 0)
124 {
125 $packetTime = floor($bufferSize * 1000000 / $speedLimit);
126 }
127
128 $bytesSent = 0;
129 $fp = fopen($fileName, "rb");
130 fseek($fp, $startPos);
131 while ($bytesSent < $contentLength && !feof($fp) && connection_status() == 0 )
132 {
133 if ($speedLimit != 0)
134 {
135 list($usec, $sec) = explode(" ", microtime());
136 $outputTimeStart = ((float)$usec + (float)$sec);
137 }
138
139 $readBufferSize = $contentLength - $bytesSent < $bufferSize ? $contentLength - $bytesSent : $bufferSize;
140 $buffer = fread($fp, $readBufferSize);
141
142 echo $buffer;
143
144 ob_flush();
145 flush();
146
147 $bytesSent += $readBufferSize;
148
149 if ($speedLimit != 0)
150 {
151 list($usec, $sec) = explode(" ", microtime());
152 $outputTimeEnd = ((float)$usec + (float)$sec);
153
154 $useTime = ((float) $outputTimeEnd - (float) $outputTimeStart) * 1000000;
155 $sleepTime = round($packetTime - $useTime);
156 if ($sleepTime > 0)
157 {
158 usleep($sleepTime);
159 }
160 }
161 }
162 return true;
163 }
164 ?>
<?php教程
002 /**
003 * <SPAN class=t_tag onclick=tagshow(event) href="tag.php?name=%CE%C4%BC%FE">文件</SPAN>传输,支持断点续传。
004 * 2g以上超大文件也有效
005 * @author MoXie
006 */
007 class Transfer {
008 /**
009 * 缓冲单元
010 */
011 const BUFF_SIZE = 5120; // 1024 * 5
012 /**
013 * 文件地址
014 * @var <String>
015 */
016 private $filePath;
017 /**
018 * 文件大小
019 * @var <String> Php超大数字 <SPAN class=t_tag onclick=tagshow(event) href="tag.php?name=%D7%D6%B7%FB">字符</SPAN>串形式描述
020 */
021 private $fileSize;
022 /**
023 * 文件类型
024 * @var <String>
025 */
026 private $mimeType;
027 /**
028 * 请求区域(范围)
029 * @var <String>
030 */
031 private $range;
032 /**
033 * 是否写入日志
034 * @var <Boolean>
035 */
036 private $isLog = false;
037 /**
038 *
039 * @param <String> $filePath 文件路径
040 * @param <String> $mimeType 文件类型
041 * @param <String> $range 请求区域(范围)
042 */
043 function __construct($filePath, $mimeType = null , $range = null) {
044 $this->filePath = $filePath;
045 $this->fileSize = sprintf('%u',filesize($filePath));
046 $this->mimeType = ($mimeType != null)?$mimeType:"application/octet-stream"; // bin
047 $this->range = trim($range);
048 }
049 /**
050 * 获取文件区域
051 * @return <Map> {'start':long,'end':long} or null
052 */
053 private function getRange() {
054 /**
055 * Range: bytes=-128
056 * Range: bytes=-128
057 * Range: bytes=28-175,382-399,510-541,644-744,977-980
058 * Range: bytes=28-175n380
059 * type 1
060 * RANGE: bytes=1000-9999
061 * RANGE: bytes=2000-9999
062 * type 2
063 * RANGE: bytes=1000-1999
064 * RANGE: bytes=2000-2999
065 * RANGE: bytes=3000-3999
066 */
067 if (!empty($this->range)) {
068 $range = preg_replace('/[s|,].*/','',$this->range);
069 $range = explode('-',substr($range,6));
070 if (count($range) < 2 ) {
071 $range[1] = $this->fileSize; // Range: bytes=-100
072 }
073 $range = array_combine(array('start','end'),$range);
074 if (empty($range['start'])) {
075 $range['start'] = 0;
076 }
077 if (!isset ($range['end']) || empty($range['end'])) {
078 $range['end'] = $this->fileSize;
079 }
080 return $range;
081 }
082 return null;
083 }
084 /**
085 * 向客户端发送文件
086 */
087 public function send() {
088 $fileHande = fopen($this->filePath, 'rb');
089 if ($fileHande) {
090 // setting
091 ob_end_clean();// clean cache
092 ob_start();
093 ini_set('output_buffering', 'Off');
094 ini_set('zlib.output_compression', 'Off');
095 $magicQuotes = get_magic_quotes_gpc();
096 set_magic_quotes_runtime(0);
097 // init
098 $lastModified = gmdate('D, d M Y H:i:s', filemtime($this->filePath)).' GMT';
099 $etag = sprintf('w/"%s:%s"',md5($lastModified),$this->fileSize);
100 $ranges = $this->getRange();
101 // headers
102 header(sprintf('Last-Modified: %s',$lastModified));
103 header(sprintf('ETag: %s',$etag));
104 header(sprintf('Content-Type: %s',$this->mimeType));
105 $disposition = 'attachment';
106 if (strpos($this->mimeType,'image/') !== FALSE) {
107 $disposition = 'inline';
108 }
109 header(sprintf('Content-Disposition: %s; filename="%s"',$disposition,basename($this->filePath)));
110
111 if ($ranges != null) {
112 if ($this->isLog) {
113 $this->log(json_encode($ranges).' '.$_SERVER['HTTP_RANGE']);
114 }
115 header('HTTP/1.1 206 Partial Content');
116 header('Accept-Ranges: bytes');
117 header(sprintf('Content-Length: %u',$ranges['end'] - $ranges['start']));
118 header(sprintf('Content-Range: bytes %s-%s/%s', $ranges['start'], $ranges['end'],$this->fileSize));
119 //
120 fseek($fileHande, sprintf('%u',$ranges['start']));
121 }else {
122 header("HTTP/1.1 200 OK");
123 header(sprintf('Content-Length: %s',$this->fileSize));
124 }
125 // read file
126 $lastSize = 0;
127 while(!feof($fileHande) && !connection_aborted()) {
128 $lastSize = sprintf("%u", bcsub($this->fileSize,sprintf("%u",ftell($fileHande))));
129 if (bccomp($lastSize,self::BUFF_SIZE) > 0) {
130 $lastSize = self::BUFF_SIZE;
131 }
132 echo fread($fileHande, $lastSize);
133 flush();
134 ob_flush();
135 }
136 set_magic_quotes_runtime($magicQuotes);
137 ob_end_flush();
138 }
139 if ($fileHande != null) {
140 fclose($fileHande);
141 }
142 }
143 /**
144 * 设置记录
145 * @param <Boolean> $isLog 是否记录
146 */
147 public function setIsLog($isLog = true) {
148 $this->isLog = $isLog;
149 }
150 /**
151 * 记录
152 * @param <String> $msg 记录信息
153 */
154 private function log($msg) {
155 try {
156 $handle = fopen('transfer_log.txt', 'a');
157 fwrite($handle, sprintf('%s : %s'.<SPAN class=t_tag onclick=tagshow(event) href="tag.php?name=PHP">PHP</SPAN>_EOL,date('Y-m-d H:i:s'),$msg));
158 fclose($handle);
159 }catch(Exception $e) {
160 // null;
161 }
162 }
163 }
164 date_default_timezone_set('Asia/Shanghai');
165 error_reporting(E_STRICT);
166 function errorHandler($errno, $errstr, $errfile, $errline) {
167 echo '<p>error:',$errstr,'</p>';
168 exit();
169 }
170 set_error_handler('errorHandler');
171 define('IS_DEBUG',true);
172
173 //
174 //
175 $filePath = '/Movie/The.Hurt.Locker.2008.x264.AC3-WAF.mkv';
176 $mimeType = 'audio/x-matroska';
177 $range = isset($_SERVER['HTTP_RANGE'])?$_SERVER['HTTP_RANGE']:null;
178 if (IS_DEBUG) {
179 // $range = "bytes=1000-1999n2000";
180 // $range = "bytes=1000-1999,2000";
181 // $range = "bytes=1000-1999,-2000";
182 // $range = "bytes=1000-1999,2000-2999";
183 }
184 set_time_limit(0);
185 $transfer = new Transfer($filePath,$mimeType,$range);
186 if (IS_DEBUG) {
187 $transfer->setIsLog(true);
188 }
189 $transfer->send();
190 ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>ajax+php 无刷新数据调用经典实例</title>
<script>
function G(id){
return document.getElementById(id);
}
function createXMLHttpRequest(){//创建XMLHttpRequest对象
if(window.ActiveXObject){//IE
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e){
return;
}
}else if(window.XMLHttpRequest){//Mozilla,firefox
try {
return new XMLHttpRequest();
} catch(e){
return;
}
}
}
function returnCity(Value,divId,at,pid){//主调函数
var xmlHttp=createXMLHttpRequest();
var url = "s.php?cid="+Value+"&at="+at+"&pid="+pid+"&mt="+Math.random(100);
//alert(url);
if (Value==""){
return false ;
}
if (xmlHttp){
callback = getReadyStateHandler(xmlHttp,divId);
xmlHttp.onreadystatechange = callback;
xmlHttp.open("GET", url,true);
xmlHttp.send(null);
}
}
function getReadyStateHandler(xmlHttp,divId){//服务器返回后处理函数
return function (){
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200){
if (xmlHttp.responseText){
G(divId).innerHTML=xmlHttp.responseText;
}else{
G(divId).innerHTML="";
}
}
}
}
}
function ajaxData(inputName,divId,action,cpid)
{
//alert(inputName);
var cityid = G(inputName).value;
var pid = G(cpid).value;
returnCity(cityid,divId,action,pid);
}
</script>
</head>
<body>
<input name="" type="text" onMouseOver="ajaxData('city_type','cityareaid','c','borough_type');" />
<div id="ajaxHtml">
</div>
</body>
</html>
//s.php文件
$Db = new Db();
$type = ( $action=='esfPice')?1:2;
$sql = "Select * from cn_loupan_city_price where city_id ='$cid' and price_type='$type'";
$query = $Db->query( $sql );
$str ='';
if( $Db->rows( $query ) )
{
$result = $Db->fetch( $query ,0);
foreach( $result as $_v => $v )
{
$str .= "<LI><A onClick="switchprop('price2_Value','".$v['city_price_show']."','price2_List','price','".$v['city_price']."')" href="javascript教程:void(0);" target=_self>".$v['city_price_show']."</A></LI>";
}
echo $str;
}
else
{
exit('可不选!');
}
//这里只讲ajax不讲数据库教程连接
www.111cn.net原他
$path ="d:pdoSpiderResult.db3";
$conn = new PDO("sqlite:$path");
$array=array('','','');
if( $conn )
{
//echo ('connection pdo success');
}
else
{
echo ('cnnection pdo fail ,plase check database server!');
}
$count=0;
$sp = new SplitWord();
foreach ($conn->query('SELECT * FROM content limit 160,80') as $row)
{
// baise info
$softtitle = mysql教程_escape_string(mb_convert_encoding($row[3],'gbk','auto')).'-js相册';//title
//file title
$softcontent = str_replace('Image/','http://g.111cn.net/javascript教程/Image/',mb_convert_encoding($row
[4],'gbk','auto'));
//file size of size
$softsize = '未知';
// file downurl
$softurl = str_replace('.zip','',$row['address']);
$filetype='.rar';
$softpath='http://g.111cn.net/javascript/'.$softurl.$filetype;
$view ='<br />效果预览地址<a href=http://g.111cn.net/javascript/'.$softurl.'
target=_blank>'.$softtitle.'</a>';//效果预览地址
preg_match_all("/(src|SRC)=["|'| ]{0,}((.*).(gif|jpg|jpeg|png|bmp))/isU",$softcontent,$img_array);
$thum = str_replace("'",'',str_replace('"','',$img_array[2][0]));
$softlinks = mysql_escape_string("{dede:link islocal='1' text='$localhost'}".$softpath."{/dede:link}");
$a = strip_tags($softcontent);
$b = $sp->SplitRMM($softtitle);
$keywords = str_replace(' ',',',$b);
$desciption = '';//desc + split word
$introduce =$softcontent.$desciption.$view;
$os ='Win2003,WinXP,Win2000,Win9X';
//call out link descript
$addsoft = "Insert into d_addonsoft(typeid,filetype,language,softtype,accredit,
os,softrank,officialUrl,officialDemo,softsize,softlinks,introduce,templet,userip,redirecturl)";
$addsoft .=" values
('$typeid','$filetype','$language','','','$os','3','','','$softsize','".$softlinks."','$introduce','','222.103.69.94','')";
mysql_query( $addsoft ) or die('addsoft'.$addsoft.mysql_error());//.$addsoft
$newid = mysql_insert_id();
// Read insert new id
$sortrank = time();
//Read the minutes and seconds when the system is currently
$click = mt_rand(1000,10000);
// Random Clicks 1000 , 10000 btween
$archives = "Insert into d_archives
(id,typeid,typeid2,sortrank,flag,ismake,channel,arcrank,click,money,title,litpic,writer,source,pubdate,senddate,mid,descripti
on,keywords)";
$archives.=" values
('$newid','$typeid','0','$sortrank','p','1','3','0','$click','0','$softtitle','$thum','$write','unkown','$sortrank','$sortran
k',1,'$desciption','$keywords')";
mysql_query($archives) or die('archives '.$archives.'|'.mysql_error()); //$archives.
$arctiny = "Insert into d_arctiny(id,typeid,typeid2,arcrank,channel,senddate,sortrank,mid) values
($newid,$typeid,0,0,3,'$sortrank','$sortrank',1)";
mysql_query( $arctiny) or die( 'arctiny'.$arctiny.mysql_error());//$arctiny.
}
echo '总共有多条',$count,"不存地的";
本站原创转载注明来源www.111cn.net
<?php
//fsocket模拟post提交
$purl = "http://localhost/netphp/test2.php?uu=rrrrrrrrrrrr";
print_r(parse_url($url));
sock_post($purl,"uu=55555555555555555");
//fsocket模拟get提交
function sock_get($url, $query)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
$head = "GET ".$info['path']."?".$info["query"]." HTTP/1.0 ";
$head .= "Host: ".$info['host']." ";
$head .= " ";
$write = fputs($fp, $head);
while (!feof($fp))
{
$line = fread($fp,4096);
echo $line;
}
}
sock_post($purl,"uu=rrrrrrrrrrrrrrrr");
function sock_post($url, $query)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
$head = "POST ".$info['path']."?".$info["query"]." HTTP/1.0 ";
$head .= "Host: ".$info['host']." ";
$head .= "Referer: http://".$info['host'].$info['path']." ";
$head .= "Content-type: application/x-www-form-urlencoded ";
$head .= "Content-Length: ".strlen(trim($query))." ";
$head .= " ";
$head .= trim($query);
$write = fputs($fp, $head);
while (!feof($fp))
{
$line = fread($fp,4096);
echo $line;
}
}
?>
相关文章
- 举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07
- 这篇文章主要介绍了c#之FileStream对象读写大文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载...2014-06-07
- 这篇文章主要介绍了vue+element+oss实现前端分片上传和断点续传,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-30
- 这篇文章主要介绍了C#使用FileStream循环读取大文件数据的方法,结合实例形式分析了FileStream文件流的形式循环读取大文件的相关操作技巧,需要的朋友可以参考下...2020-06-25
php 超大文件下载程序[http 缓存协商,Etag标记,断点续传]
<?php教程 002 $file_path = './download/download_cn.rar'; 003 004 //使用方法 005 downFile($file_path); 006 007 // 服务器文件路径,下载文件名字(默认...2016-11-25- 断点续传指的是在上传时,将上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传,下面我们来看看php 断点续传功能的实现方法吧。 <?...2016-11-25
- 这篇文章主要为大家介绍了Blob对象实现文件上传下载示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...2023-01-06
修改PHP配置文件上传大文件几种方法(apache/nginx)
在php.ini中如果我们不对 post_max_size,upload_max_filesize 这些参数进行修改,默认最多只能上传2MB的文件了,如果几十MB或更大的就无法上传了,下面我来介绍修改PHP配置...2016-11-25- function xiazai($file_dir,$file_name) //参数说明: //file_dir:文件所在目录 //file_name:文件名 { $file_dir = chop($file_dir);//去掉路径中多余的空格...2016-11-25
- 下面小编就为大家分享一篇java 文件下载支持中文名称的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-25
- 在php中文件下载会利用到header fopen fread三个主要函数,同时还有一些辅助函数如判断文件存在file_exists is_file等函数,下面我们来看一款文件下载可以限制下载速度实...2016-11-25
.NET的file文件上传控件使用方法 修改web.config文件上传大文件
这篇文章主要介绍了.NET修改web.config文件上传大文件的方法,大家参考使用吧...2021-09-22- 这里为各位提供一款远程文件下载代码,我们可以把远程的文件用php下载到本地指定的目录,希望文章对你有帮助。 代码如下 复制代码 class downl...2016-11-25
- //author:heaven //文件下载 function download($file_dir,$file_name) //参数说明: //file_dir:文件所在目录 //file_name:文件名 { $file_dir = chop($fi...2016-11-25
- php简单文件下载过滤判断函数 if(strpos($fileurl, ':/'))//远程文件 { header("Location: $fileurl"); } else//本地文件 { if($d == 0) { header(...2016-11-25
- 本文章提供的三款文件下载代码有二款是支持本地服务器文件下载的,另一款支持下载远程服务器上的文件下载到本地哦。 代码如下 复制代码 func...2016-11-25
- 本篇文章结合实例为大家介绍了php下载远程大文件(获取远程文件大小)的方法,有需要的朋友就来参考一下吧。 废话不多说,直接上代码 代码如下复制代码 <?php /...2017-07-06
- 文章介绍了利用php来实现读取文件并且下载的代码,php要下载文件必须用到header函数,大家可参考一下。 代码如下 复制代码 <?php $file = 'm...2016-11-25
- 这篇文章主要为大家详细介绍了php使用curl实现ftp文件下载功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了php实现ftp文件下载功能,供...2017-07-06