最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

php實(shí)現(xiàn)斷點(diǎn)續(xù)傳大文件示例代碼

 更新時(shí)間:2020年06月19日 15:12:44   作者:錢海海  
這篇文章主要介紹了如何用php實(shí)現(xiàn)斷點(diǎn)續(xù)傳大文件,文中代碼非常細(xì)致,幫助大家學(xué)習(xí)和參考,感興趣的朋友可以了解下

一、斷點(diǎn)續(xù)傳原理

所謂斷點(diǎn)續(xù)傳,也就是要從文件已經(jīng)下載的地方開始繼續(xù)下載。在以前版本的 HTTP 協(xié)議是不支持?jǐn)帱c(diǎn)的,HTTP/1.1 開始就支持了。一般斷點(diǎn)下載時(shí)才用到 Range 和 Content-Range 實(shí)體頭。

不使用斷點(diǎn)續(xù)傳

get /down.zip http/1.1
accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
excel, application/msword, application/vnd.ms-powerpoint, */*
accept-language: zh-cn
accept-encoding: gzip, deflate
user-agent: mozilla/4.0 (compatible; msie 5.01; windows nt 5.0)
connection: keep-alive

 服務(wù)器收到請(qǐng)求后,按要求尋找請(qǐng)求的文件,提取文件的信息,然后返回給瀏覽器,返回信息如下:

HTTP/1.1 200 Ok
content-length=106786028
accept-ranges=bytes
date=mon, 30 apr 2001 12:56:11 gmt
etag=w/"02ca57e173c11:95b"
content-type=application/octet-stream
server=microsoft-iis/5.0
last-modified=mon, 30 apr 2001 12:56:11 gmt

使用斷點(diǎn)續(xù)傳

GET /down.zip HTTP/1.0
User-Agent: NetFox
RANGE: bytes=2000070-
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

多了這么一行Range: bytes=2000070-

這一行的意思就是告訴服務(wù)器down.zip這個(gè)文件從2000070字節(jié)開始傳,前面的字節(jié)不用傳了。
Range的完整格式是:

Range: bytes=startOffset-targetOffset/sum [表示從startOffset讀取,一直讀取到targetOffset位置,讀取總數(shù)為sum直接]
 
Range: bytes=startOffset-targetOffset [字節(jié)總數(shù)也可以去掉]

服務(wù)器收到這個(gè)請(qǐng)求以后,返回的信息如下:

HTTP/1.1 206 Partial Content
content-length=106786028
content-range=bytes 2000070-106786027/106786028
date=mon, 30 apr 2001 12:55:20 gmt
etag=w/"02ca57e173c11:95b"
content-type=application/octet-stream
server=microsoft-iis/5.0
last-modified=mon, 30 apr 2001 12:55:20 gmt

和前面服務(wù)器返回的信息比較一下,就會(huì)發(fā)現(xiàn)增加了一行:

Content-Range=bytes 2000070-106786027/106786028

返回的代碼也改為206了,而不再是200了。

HTTP/1.1 206 Partial Content

知道了以上原理,就可以進(jìn)行斷點(diǎn)續(xù)傳的編程了。

二、PHP實(shí)現(xiàn)

/** php下載類,支持?jǐn)帱c(diǎn)續(xù)傳
 * download: 下載文件
 * setSpeed: 設(shè)置下載速度
 * getRange: 獲取header中Range
 */
 
class FileDownload{
 
 /** 下載
 * @param String $file 要下載的文件路徑
 * @param String $name 文件名稱,為空則與下載的文件名稱一樣
 * @param boolean $reload 是否開啟斷點(diǎn)續(xù)傳
 */
 public function download($file, $name='', $reload=false){
 $fp = @fopen($file, 'rb');
 if($fp){
 if($name==''){
 $name = basename($file);
 }
 $header_array = get_headers($file, true);
 //var_dump($header_array);die;
 // 下載本地文件,獲取文件大小
 if (!$header_array) {
 $file_size = filesize($file);
 } else {
 $file_size = $header_array['Content-Length'];
 }
 $ranges = $this->getRange($file_size);
 $ua = $_SERVER["HTTP_USER_AGENT"];//判斷是什么類型瀏覽器
 header('cache-control:public');
 header('content-type:application/octet-stream'); 
 
 $encoded_filename = urlencode($name);
 $encoded_filename = str_replace("+", "%20", $encoded_filename);
 
 //解決下載文件名亂碼
 if (preg_match("/MSIE/", $ua) || preg_match("/Trident/", $ua) ){ 
 header('Content-Disposition: attachment; filename="' .$encoded_filename . '"');
 } else if (preg_match("/Firefox/", $ua)) {
 header('Content-Disposition: attachment; filename*="utf8\'\'' . $name . '"');
 }else if (preg_match("/Chrome/", $ua)) {
 header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
 } else {
 header('Content-Disposition: attachment; filename="' . $name . '"');
 }
 //header('Content-Disposition: attachment; filename="' . $name . '"');
 
 if($reload && $ranges!=null){ // 使用續(xù)傳
 header('HTTP/1.1 206 Partial Content');
 header('Accept-Ranges:bytes');
 
 // 剩余長度
 header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));
 
 // range信息
 header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
 //file_put_contents('test.log',sprintf('content-length:%u',$ranges['end']-$ranges['start']),FILE_APPEND);
 // fp指針跳到斷點(diǎn)位置
 fseek($fp, sprintf('%u', $ranges['start']));
 }else{
 file_put_contents('test.log','2222',FILE_APPEND);
 header('HTTP/1.1 200 OK');
 header('content-length:'.$file_size);
 }
 
 while(!feof($fp)){
 //echo fread($fp, round($this->_speed*1024,0));
 //echo fread($fp, $file_size);
 echo fread($fp, 4096);
 ob_flush();
 }
 
 ($fp!=null) && fclose($fp);
 }else{
 return '';
 }
 }
 
 /** 設(shè)置下載速度
 * @param int $speed
 */
 public function setSpeed($speed){
 if(is_numeric($speed) && $speed>16 && $speed<4096){
 $this->_speed = $speed;
 }
 }
 
 /** 獲取header range信息
 * @param int $file_size 文件大小
 * @return Array
 */
 private function getRange($file_size){
 //file_put_contents('range.log', json_encode($_SERVER), FILE_APPEND);
 if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){
 $range = $_SERVER['HTTP_RANGE'];
 $range = preg_replace('/[\s|,].*/', '', $range);
 $range = explode('-', substr($range, 6));
 if(count($range)<2){
 $range[1] = $file_size;
 }
 $range = array_combine(array('start','end'), $range);
 if(empty($range['start'])){
 $range['start'] = 0;
 }
 if(empty($range['end'])){
 $range['end'] = $file_size;
 }
 return $range;
 }
 return null;
 }
}
 
$obj = new FileDownload();
$obj->download('http://down.golaravel.com/laravel/laravel-master.zip','', true);

以上就是php實(shí)現(xiàn)斷點(diǎn)續(xù)傳大文件示例代碼的詳細(xì)內(nèi)容,更多關(guān)于php 斷點(diǎn)續(xù)傳大文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • yii數(shù)據(jù)庫的查詢方法

    yii數(shù)據(jù)庫的查詢方法

    這篇文章主要介紹了yii數(shù)據(jù)庫的查詢方法,結(jié)合實(shí)例簡單分析了直接查詢和使用criteria進(jìn)行查詢的技巧,需要的朋友可以參考下
    2015-12-12
  • Yii框架ACF(accessController)簡單權(quán)限控制操作示例

    Yii框架ACF(accessController)簡單權(quán)限控制操作示例

    這篇文章主要介紹了Yii框架ACF(accessController)簡單權(quán)限控制操作,結(jié)合實(shí)例形式分析了Yii框架簡單權(quán)限控制操作參數(shù)設(shè)置與使用技巧,需要的朋友可以參考下
    2019-04-04
  • PHP對(duì)接微信公眾平臺(tái)消息接口開發(fā)流程教程

    PHP對(duì)接微信公眾平臺(tái)消息接口開發(fā)流程教程

    這篇文章主要介紹了PHP對(duì)接微信公眾平臺(tái)消息接口開發(fā)流程,如何使用PHP版接口操作公眾平臺(tái)消息,需要的朋友可以參考下
    2014-03-03
  • PHP中將網(wǎng)頁導(dǎo)出為Word文檔的代碼

    PHP中將網(wǎng)頁導(dǎo)出為Word文檔的代碼

    今天要探討的是PHP網(wǎng)頁導(dǎo)出Word文檔的方法,使用其他語言的朋友也可以參考,因?yàn)樵硎遣畈欢嗟?/div> 2012-05-05
  • 用PHP讀取超大文件的實(shí)例代碼

    用PHP讀取超大文件的實(shí)例代碼

    數(shù)據(jù)量大帶來的問題就是單個(gè)文件很大,能夠打開這個(gè)文件相當(dāng)不容易,記事本就不要指望了,果斷死機(jī)
    2012-04-04
  • PHP寫UltraEdit插件腳本實(shí)現(xiàn)方法

    PHP寫UltraEdit插件腳本實(shí)現(xiàn)方法

    PHP寫UltraEdit插件腳本實(shí)現(xiàn)方法,需要的朋友可以從參考下。
    2011-12-12
  • ThinkPHP3.2.3框架Memcache緩存使用方法實(shí)例總結(jié)

    ThinkPHP3.2.3框架Memcache緩存使用方法實(shí)例總結(jié)

    這篇文章主要介紹了ThinkPHP3.2.3框架Memcache緩存使用方法,結(jié)合實(shí)例形式總結(jié)分析看thinkPHP框架下Memcache緩存各種調(diào)用方法與配置相關(guān)操作技巧,需要的朋友可以參考下
    2019-04-04
  • php fsockopen解決辦法 php實(shí)現(xiàn)多線程

    php fsockopen解決辦法 php實(shí)現(xiàn)多線程

    有沒有辦法在php中實(shí)現(xiàn)多線程呢?假設(shè)你正在寫一個(gè)基于多臺(tái)服務(wù)器的php應(yīng)用,理想的情況時(shí)同時(shí)向多臺(tái)服務(wù)器發(fā)送請(qǐng)求,而不是一臺(tái)接一臺(tái)??梢詫?shí)現(xiàn)嗎?回答是當(dāng)然可以,下面看解決方法
    2014-01-01
  • PHP簡單的MVC框架實(shí)現(xiàn)方法

    PHP簡單的MVC框架實(shí)現(xiàn)方法

    在PHP中使用MVC越來越流行了,特別是在一些開源的框架當(dāng)中。本篇給大家介紹php簡單的mvc框架實(shí)現(xiàn)方法,對(duì)php簡單的mvc框架相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • PHP中的常見魔術(shù)方法功能作用及用法實(shí)例

    PHP中的常見魔術(shù)方法功能作用及用法實(shí)例

    這篇文章主要介紹了PHP中的常見魔術(shù)方法功能作用及用法實(shí)例,本文講解了構(gòu)造函數(shù)和析構(gòu)函數(shù)__construct()和__desctruct()以及屬性重載(Property Overloading)__get()和、__set()、__isset()等等魔術(shù)方法,需要的朋友可以參考下
    2015-07-07

最新評(píng)論

习水县| 于都县| 塘沽区| 开封市| 武城县| 裕民县| 吉木萨尔县| 麻栗坡县| 宁蒗| 桑日县| 桃园市| 吉首市| 玛多县| 盐亭县| 西华县| 凤山县| 蓬溪县| 泰顺县| 高台县| 盘山县| 克什克腾旗| 三门县| 宜昌市| 鹤山市| 马山县| 白水县| 商河县| 太湖县| 北宁市| 华坪县| 灌南县| 玛纳斯县| 通渭县| 康乐县| 沧州市| 罗甸县| 金溪县| 苗栗市| 郯城县| 宣恩县| 新干县|