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

PHP實(shí)現(xiàn)文件下載斷點(diǎn)續(xù)傳詳解

 更新時(shí)間:2014年10月15日 13:36:45   投稿:junjie  
這篇文章主要介紹了PHP實(shí)現(xiàn)文件下載斷點(diǎn)續(xù)傳詳解,本文講解了載斷點(diǎn)續(xù)傳的實(shí)現(xiàn)理解,并給出了實(shí)現(xiàn)代碼,需要的朋友可以參考下

如果我們的網(wǎng)站提供文件下載的服務(wù),那么通常我們都希望下載可以斷點(diǎn)續(xù)傳(Resumable Download),也就是說(shuō)用戶可以暫停下載,并在未來(lái)的某個(gè)時(shí)間從暫停處繼續(xù)下載,而不必重新下載整個(gè)文件。

通常情況下,Web服務(wù)器(如Apache)會(huì)默認(rèn)開(kāi)啟對(duì)斷點(diǎn)續(xù)傳的支持。因此,如果直接通過(guò)Web服務(wù)器來(lái)提供文件的下載,可以不必做特別的配置,即可享受到斷點(diǎn)續(xù)傳的好處。由于這些文件直接通過(guò)Web服務(wù)器來(lái)提供下載,后端腳本無(wú)法對(duì)這個(gè)下載過(guò)程進(jìn)行控制。這對(duì)于僅提供公開(kāi)、靜態(tài)文件的網(wǎng)站來(lái)說(shuō)不是問(wèn)題,但對(duì)于需要提供私有、動(dòng)態(tài)文件的網(wǎng)站來(lái)說(shuō),直接通過(guò)Web服務(wù)器來(lái)提供下載就無(wú)法滿足需求了。這時(shí),就需要在編寫(xiě)后臺(tái)腳本程序時(shí),加入對(duì)斷點(diǎn)續(xù)傳的支持。

本文將以PHP為例,簡(jiǎn)要介紹實(shí)現(xiàn)文件下載斷點(diǎn)續(xù)傳的方法。

原理

斷點(diǎn)續(xù)傳的原理還是比較直觀的。

HTTP協(xié)議規(guī)定了如何傳輸某個(gè)資源的一部分,而不是全部。比如,有一個(gè)文件的大小是1000字節(jié),瀏覽器可以只請(qǐng)求該文件的前300個(gè)字節(jié),或者只請(qǐng)求第500到第1000個(gè)字節(jié)。通過(guò)這種方式,就可以不必在一次請(qǐng)求中傳輸某個(gè)資源的全部?jī)?nèi)容,而是發(fā)起多次請(qǐng)求,每次僅請(qǐng)求其中的一部分內(nèi)容。等所有這些請(qǐng)求都返回之后,再把得到的內(nèi)容一塊一塊的拼接起來(lái)得到完整的資源。

實(shí)現(xiàn)斷點(diǎn)續(xù)傳就是要利用HTTP協(xié)議的上述特性。當(dāng)用戶暫停下載的時(shí)候,瀏覽器會(huì)記錄已經(jīng)下載到什么位置,當(dāng)用戶在未來(lái)某一時(shí)間恢復(fù)下載時(shí),就可以從上次暫停的位置繼續(xù)下載,而不必從頭開(kāi)始。

實(shí)現(xiàn)

由于部分傳輸不是強(qiáng)制的,服務(wù)器可以支持也可以不支持,所以,我們需要在程序中告訴瀏覽器,它請(qǐng)求的資源是否支持部分傳輸。這可以通過(guò)設(shè)置HTTP的 Accept-Ranges 響應(yīng)頭信息來(lái)實(shí)現(xiàn)。PHP代碼如下:

復(fù)制代碼 代碼如下:

header('Accept-Ranges: bytes');

Accept-Ranges: bytes 告訴瀏覽器,該資源支持以字節(jié)為單位的部分傳輸。這個(gè)響應(yīng)頭需要附加在支持部分傳輸?shù)乃匈Y源上。

當(dāng)接受到一個(gè)請(qǐng)求時(shí),我們需要從瀏覽器的請(qǐng)求中提取瀏覽器具體是在請(qǐng)求資源的哪一個(gè)部分。這個(gè)信息是通過(guò) Range 請(qǐng)求頭來(lái)傳遞的。在PHP中,它被存儲(chǔ)在$_SERVER['HTTP_RANGE']中。我們需要檢查這個(gè)變量是否定義了,如果定義了,則使用該值,否則,就將range設(shè)為整個(gè)資源。

復(fù)制代碼 代碼如下:

$range = "0-". ($content_length-1);
if(isset($_SERVER['HTTP_RANGE'])){
    $range = $_SERVER['HTTP_RANGE'];
}

接下來(lái),就需要分析 $range 的值,來(lái)決定返回資源的哪一部分內(nèi)容??赡艿娜≈凳纠?br />
復(fù)制代碼 代碼如下:

100-200 // 第100到第200字節(jié)
500-    // 第500字節(jié)到文件末尾
-1000   // 最后的1000個(gè)字節(jié)

這里需要注意,得到一個(gè)Range之后,你需要對(duì)它的取值進(jìn)行檢驗(yàn),包括:

1.開(kāi)始位置非負(fù)
2.結(jié)束位置需要大于開(kāi)始位置
3.開(kāi)始位置需要小于文件長(zhǎng)度減一 (因?yàn)檫@里的位置索引是從0開(kāi)始的)
4.若結(jié)束位置大于文件長(zhǎng)度減一,則需要把它的值設(shè)置為文件長(zhǎng)度減一

如果Range的取值不合法,則需要終止程序并告知瀏覽器:

復(fù)制代碼 代碼如下:

header('HTTP/1.1 416 Requested Range Not Satisfiable');

為了保持文章簡(jiǎn)潔,具體的校驗(yàn)代碼這里就不提供了。下面假定你已經(jīng)校驗(yàn)了Range的取值,并得到了 $start 和 $end 兩個(gè)變量,分別表示開(kāi)始位置和結(jié)束位置。

接下來(lái)要做的就是把文件的對(duì)應(yīng)部分的內(nèi)容發(fā)送給瀏覽器。不過(guò)要注意的是,這里涉及到需要發(fā)送多個(gè)HTTP響應(yīng)頭信息,具體如下:

復(fù)制代碼 代碼如下:

header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges: bytes');
header("Content-Range: bytes $start-$end/$filesize");
$length = $end - $start + 1;
header("Content-Length: $length");

/* 輸出文件的指定部分 */


這里的$length需要注意一下,它的取值是本次傳輸?shù)膬?nèi)容的長(zhǎng)度,而不是整個(gè)文件的長(zhǎng)度。另外需要注意的一點(diǎn)是,這里的HTTP狀態(tài)碼是206,不是200。

總結(jié)

文件下載的斷點(diǎn)續(xù)傳實(shí)際上是利用了HTTP協(xié)議中對(duì)傳輸部分文件的支持。而HTTP協(xié)議的這一特性不僅可以用于實(shí)現(xiàn)斷點(diǎn)續(xù)傳,客戶端程序也可以利用它來(lái)實(shí)現(xiàn)多線程下載。

在實(shí)現(xiàn)斷點(diǎn)續(xù)傳的過(guò)程中,需要注意正確設(shè)置各種HTTP頭信息。錯(cuò)誤的頭信息將導(dǎo)致用戶下載到的文件損壞,無(wú)法使用。

相關(guān)文章

  • php自動(dòng)更新版權(quán)信息顯示的方法

    php自動(dòng)更新版權(quán)信息顯示的方法

    這篇文章主要介紹了php自動(dòng)更新版權(quán)信息顯示的方法,實(shí)例分析了php根據(jù)時(shí)間選擇顯示方式,需要的朋友可以參考下
    2015-06-06
  • PHP采用get獲取url漢字出現(xiàn)亂碼的解決方法

    PHP采用get獲取url漢字出現(xiàn)亂碼的解決方法

    這篇文章主要介紹了PHP采用get獲取url漢字出現(xiàn)亂碼的解決方法,是很多PHP程序員都曾遇到的問(wèn)題,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-11-11
  • PHP中的閉包function()?use()?{}使用場(chǎng)景和技巧

    PHP中的閉包function()?use()?{}使用場(chǎng)景和技巧

    由于存在函數(shù)內(nèi)部不能訪問(wèn)全局作用的,所以就需要一種可以引入上一級(jí)作用域的語(yǔ)法結(jié)構(gòu),可以通過(guò)use使用函數(shù)聲明時(shí)所在作用域的變量的值。php的閉包可能不常用,但是在某些場(chǎng)合之下還是可以考慮用php的閉包來(lái)實(shí)現(xiàn)某些功能的。
    2022-12-12
  • 使用ltrace工具跟蹤PHP庫(kù)函數(shù)調(diào)用的方法

    使用ltrace工具跟蹤PHP庫(kù)函數(shù)調(diào)用的方法

    這篇文章主要介紹了使用ltrace工具跟蹤PHP庫(kù)函數(shù)調(diào)用的方法,結(jié)合實(shí)例形式分析了ltrace工具用來(lái)跟蹤PHP庫(kù)函數(shù)運(yùn)行時(shí)間的相關(guān)技巧,需要的朋友可以參考下
    2016-04-04
  • php字符串使用詳細(xì)了解

    php字符串使用詳細(xì)了解

    PHP中的字符串是一種類C風(fēng)格的字符串,只不過(guò)已經(jīng)得到了很好的封裝。在PHP中,可以將字符串包含在一對(duì)雙引號(hào)或一對(duì)單引號(hào)之中,我們來(lái)看一看php的字符串都有哪些特點(diǎn)
    2022-12-12
  • PHP設(shè)計(jì)模式之注冊(cè)樹(shù)模式分析

    PHP設(shè)計(jì)模式之注冊(cè)樹(shù)模式分析

    這篇文章主要介紹了PHP設(shè)計(jì)模式之注冊(cè)樹(shù)模式,結(jié)合實(shí)例形式詳細(xì)分析了注冊(cè)樹(shù)模式的概念、原理、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2018-01-01
  • PHP實(shí)現(xiàn)倒計(jì)時(shí)功能

    PHP實(shí)現(xiàn)倒計(jì)時(shí)功能

    這篇文章主要為大家詳細(xì)介紹了PHP實(shí)現(xiàn)倒計(jì)時(shí)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • PHP stream_context_create()作用和用法分析

    PHP stream_context_create()作用和用法分析

    創(chuàng)建并返回一個(gè)文本數(shù)據(jù)流并應(yīng)用各種選項(xiàng),可用于fopen(),file_get_contents()等過(guò)程的超時(shí)設(shè)置、代理服務(wù)器、請(qǐng)求方式、頭信息設(shè)置的特殊過(guò)程。
    2011-03-03
  • 基于PHP+Ajax實(shí)現(xiàn)表單驗(yàn)證的詳解

    基于PHP+Ajax實(shí)現(xiàn)表單驗(yàn)證的詳解

    本篇文章是對(duì)PHP+Ajax實(shí)現(xiàn)表單驗(yàn)證的代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • PHP內(nèi)部實(shí)現(xiàn)打亂字符串順序函數(shù)str_shuffle的方法

    PHP內(nèi)部實(shí)現(xiàn)打亂字符串順序函數(shù)str_shuffle的方法

    這篇文章主要給大家介紹了關(guān)于PHP內(nèi)部實(shí)現(xiàn)打亂字符串順序函數(shù)str_shuffle的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02

最新評(píng)論

二连浩特市| 汶上县| 南丰县| 芒康县| 舒城县| 湘阴县| 康定县| 祁东县| 奉节县| 梓潼县| 那坡县| 江门市| 新泰市| 密山市| 故城县| 灵台县| 新津县| 井冈山市| 东台市| 鸡东县| 和龙市| 东丰县| 佛学| 千阳县| 新宁县| 突泉县| 玉林市| 阜新市| 岗巴县| 张家界市| 大洼县| 镇巴县| 苍南县| 萨迦县| 虎林市| 商洛市| 兰西县| 奉节县| 大兴区| 长汀县| 绥德县|