程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 關於使用PHP向客戶端發送文件-示例代碼解釋

關於使用PHP向客戶端發送文件-示例代碼解釋

編輯:關於PHP編程

[php] 
<?php  
function downloadFile( $fullPath ){  
 
  // Must be fresh start  
  if( headers_sent() )  //check if any header has been sent 
    die('Headers Sent');  //Equivalent to exit() 
 
  // Required for some browsers  
  if(ini_get('zlib.output_compression')) //Gets the value of a configuration option 
    ini_set('zlib.output_compression', 'Off'); //該模塊允許PHP透明的讀取和寫入gzip(.gz)壓縮文件 
 
  // File Exists?  
  if( file_exists($fullPath) ){  
     
    // Parse Info / Get Extension  
    $fsize = filesize($fullPath);  
    $path_parts = pathinfo($fullPath);//返回文件路徑的信息  
    /*
    $path_parts = pathinfo("/www/htdocs/index.html");
    echo $path_parts["dirname"] . "\n";
    echo $path_parts["basename"] . "\n";
    echo $path_parts["extension"] . "\n";//後綴名
    返回的信息分別為:
    /www/htdocs
    index.html
    html
    */ 
    $ext = strtolower($path_parts["extension"]); //將字符串轉化為小寫 
     
    // Determine Content Type  
    switch ($ext) {  
      case "pdf": $ctype="application/pdf"; break;  
      case "exe": $ctype="application/octet-stream"; break;  
      case "zip": $ctype="application/zip"; break;  
      case "doc": $ctype="application/msword"; break;  
      case "xls": $ctype="application/vnd.ms-excel"; break;  
      case "ppt": $ctype="application/vnd.ms-powerpoint"; break;  
      case "gif": $ctype="image/gif"; break;  
      case "png": $ctype="image/png"; break;  
      case "jpeg":  
      case "jpg": $ctype="image/jpg"; break;  
      default: $ctype="application/force-download";  
    }  
  
    header("Pragma: public"); // required 指明響應可被任何緩存保存 
    /*
     The same that "Cache-Control: public"
     public:指明響應可被任何緩存保存,即便該響應通常是不可緩存的或只在非共享緩存裡是可緩存的。
     private:指明響應消息的部分或所有部分是為一個用戶准備的並且不得被共享緩存保存。可以使源服
             務器可以聲明響應的特定部分來針對某一用戶並且對其他用戶的請求是無效的。一個私有
            (非共享)緩存可以緩存此響應。
     no-cache:如果no-cache緩存控制指令沒有指定一個field-name,那麼一個緩存不能利用此響應在沒
               有通過源服務器對它進行成功重驗證的情況下去滿足後續的請求。這允許源服務器去防止響
               應被緩存保存,即使此緩存已被設置可以返回陳舊響應給客戶端。 
               如果no-cache緩存控制指令指定一個或多個field-name,那麼緩存可以利用此響應去滿足
               後續的請求,但這要受限於對緩存的其它限制。然而,指定的filed-name必須不能在後續請
               求的響應裡被發送如果此響應沒有在源服務器那裡得到成功重驗證。這允許源服務器能防止
               緩存去重利用響應裡的某些頭域,但仍然允許緩存能保存響應剩余部分。
    /*
        The Pragma header specifies directives for proxy and gateway systems. 
     Since many proxy systems may exist between a client and server, Pragma 
     headers must pass through each proxy. When the Pragma header reaches 
     the server, the header may be ignored by the server software.
 
        The only directive defined in HTTP/1.0 is the no-cache directive. It is
     used to tell caching proxies to contact the server for the requested 
     document, instead of using its local cache. This allows the client to 
     request the most up-to-date document from the original web server,
     without receiving a cached copy from an intermediate proxy server.
 
       The Pragma header is an HTTP 1.0 feature, and is maintained in HTTP 1.1 
     for backward compatibility. No new Pragma directives will be defined in 
     the future.
     */ 
    header("Expires: 0");  
    /*
     Expires實體頭域(entity-header)給出了在何時之後響應即被視為陳舊的。一個陳舊的緩存項
            不能被緩存(一個代理緩存或一個用戶代理的緩存)返回給客戶端,除非此緩存項被源服務器
            (或者被一個擁有實體的保鮮副本的中間緩存)驗證。
            0表示立即過期,就是不緩存的意思。
     */ 
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");  
    /*
        post-check and pre-check cache control directives must appear together 
     in pairs other wise they are ignored.
           */ 
    header("Cache-Control: private",false); // required for certain browsers  
    header("Content-Type: $ctype");  
    header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" ); 
     header("Content-Transfer-Encoding: binary");  
    header("Content-Length: ".$fsize);  
    ob_clean(); //Clean (erase) the output buffer 
    flush(); //刷新PHP程序的緩沖,而不論PHP執行在何種情況下(CGI ,web服務器等等)。該函數將當前為止程序的所有輸出發送到用戶的浏覽器。  
    readfile( $fullPath ); //讀入一個文件並寫入到輸出緩沖。 
 
  } else  
    die('File Not Found');  
 
}  
?>  

這是PHP手冊上的示例代碼,自己看不懂,就把一條條的翻譯出來。

下面是

 © kekehu / 技術資源 / 2009.02.17 / 10:15 / 4246PV

    網頁的緩存是由HTTP消息頭中的“Cache-control”來控制的,常見的取值有private、no-cache、max-age、must-revalidate等,默認為private。其作用根據不同的重新浏覽方式分為以下幾種情況:

(1) 打開新窗口
    值為private、no-cache、must-revalidate,那麼打開新窗口訪問時都會重新訪問服務器。
而如果指定了max-age值,那麼在此值內的時間裡就不會重新訪問服務器,例如:
Cache-control: max-age=5(表示當訪問此網頁後的5秒內再次訪問不會去服務器)

(2) 在地址欄回車
    值為private或must-revalidate則只有第一次訪問時會訪問服務器,以後就不再訪問。
    值為no-cache,那麼每次都會訪問。
    值為max-age,則在過期之前不會重復訪問。

(3) 按後退按扭
   值為private、must-revalidate、max-age,則不會重訪問,
   值為no-cache,則每次都重復訪問

(4) 按刷新按扭
  無論為何值,都會重復訪問

Cache-control值為“no-cache”時,訪問此頁面不會在Internet臨時文章夾留下頁面備份。

另外,通過指定“Expires”值也會影響到緩存。例如,指定Expires值為一個早已過去的時間,那麼訪問此網時若重復在地址欄按回車,那麼每次都會重復訪問: Expires: Fri, 31 Dec 1999 16:00:00 GMT

比如:禁止頁面在IE中緩存

http響應消息頭部設置:

CacheControl = no-cache
Pragma=no-cache
Expires = -1

Expires是個好東東,如果服務器上的網頁經常變化,就把它設置為-1,表示立即過期。如果一個網頁每天凌晨1點更新,可以把Expires設置為第二天的凌晨1點。

當HTTP1.1服務器指定CacheControl = no-cache時,浏覽器就不會緩存該網頁。

舊式 HTTP 1.0 服務器不能使用 Cache-Control 標題。
所以為了向後兼容 HTTP 1.0 服務器,IE使用Pragma:no-cache 標題對 HTTP 提供特殊支持。
如果客戶端通過安全連接 (https://)與服務器通訊,且服務器在響應中返回 Pragma:no-cache 標題,
則 Internet Explorer不會緩存此響應。注意:Pragma:no-cache 僅當在安全連接中使用時才防止緩存,如果在非安全頁中使用,處理方式與 Expires:-1相同,該頁將被緩存,但被標記為立即過期。
作者:wolinxuebin

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved