2012-09-17 131 views
1

所以首先我想告訴我,我是相當新手頭使用和播放輸出緩衝區。所以即時通訊開發PHP的portlet liferay和我有一些文件下載的問題。我試圖用'一個href'來做到這一點,但問題是,通過PHP上傳的文件不可用,直到Apache刷新,所以我試着用header()函數的另一種方式。php force下載使用標題()破解下載的文件

所以我會盡力解釋我的問題。當我在簡單的PHP項目嘗試下面的代碼,它工作正常:

<?php 

$path = "/mysecretdir/upload/"; // change the path to fit your websites document structure 
$fullPath = $path.$_GET['download_file']; 

if ($fd = fopen ($fullPath, "r")) { 

    $fsize = filesize($fullPath); 

    $path_parts = pathinfo($fullPath); 
    $ext = strtolower($path_parts["extension"]); 

    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": 
      $ctype = "image/jpg"; 
      break; 
     case "jpg": 
      $ctype = "image/jpg"; 
      break; 
     case "mp3": 
      $ctype = "audio/mp3"; 
      break; 
     case "wav": 
      $ctype = "audio/x-wav"; 
      break; 
     case "wma": 
      $ctype = "audio/x-wav"; 
      break; 
     case "mpeg": 
      $ctype = "video/mpeg"; 
      break; 
     case "mpg": 
      $ctype = "video/mpeg"; 
      break; 
     case "mpe": 
      $ctype = "video/mpeg"; 
      break; 
     case "mov": 
      $ctype = "video/quicktime"; 
      break; 
     case "avi": 
      $ctype = "video/x-msvideo"; 
      break; 
     case "src": 
      $ctype = "plain/text"; 
      break; 
     default: 
      $ctype = "application/force-download"; 
    } 

    header("Pragma: public"); 

    header("Expires: 0"); 

    header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 

    header("Cache-Control: private",false); 

    header("Content-type: " . $ctype); 

    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); 

    header("Content-Transfer-Encoding: binary"); 

    //header("Content-length: $fsize"); 
    header("Cache-control: public"); //use this to open files directly  

    while(!feof($fd)) { 
     echo fread($fd, 4096); 
    flush(); 
    } 
} 
fclose ($fd); 
?> 

從的index.php IM與HREF = 「的download.php download_file = /事/?」

好了,但現在的點調用它。當我在liferay portlet中使用它時,該文件很奇怪。它將整個生成的HTML文件放入創建的文件中。所以它壞了。我不知道爲什麼。我不知道如果標題是從其他地方發送一些信息,也不知道如何解決它。

我正在尋找一些解決方案的小時,但不知道如何使標題「會話」,因爲我認爲他們有問題。如果沒有回聲,它只會打印文件的內容,並在其他項目中 - 更簡單的PHP應用程序不作爲它的工作門戶的一部分!但也許我錯了。

那麼請有人能幫助我嗎?有任何建議嗎?

+2

您的代碼允許惡意用戶下載服務器上的任何文件。考慮'download.php?download_file = ../../../../etc/passwd'。而且,整個FOPEN/FREAD業務是毫無意義的。只需使用'readfile()'。加...爲什麼硬編碼MIME類型?有[finfo](http://php.net/finfo)允許你處理任何服務器知道的mimetype。 –

+0

我只是在尋找一些解決方案,這是我發現並嘗試使用的一種解決方案。那我能做些什麼來連結它?並且它仍然不能解決我的問題與輸出:( –

回答

1

我不能幫你解決特定的php-portlet問題(我從來沒有使用過Liferay和php),但它聽起來像是讓你在你的下載文件「周圍」生成整個頁面的HTML。這是您在呈現portlet時所得到的結果:portlet始終嵌入在HTML頁面中,因此無法使用portlet的標準呈現輸出在HTTP級別提供特定的標頭。

你想要的是portlet的serveResource生命週期階段。這將允許您提供不屬於頁面的內容,但您可以完全控制下載和HTTP標頭。如何用php portlet來做到這一點,我將不得不離開你。

編輯(附加信息):如您在評論中問道,我發現了一箇舊的(可能需要進行調整)Wiki article談到有關使用狀態=獨家做同樣的伎倆 - 代替的serveResource我如上所述。我不知道這是由於文章的年齡或者PHP portlet不支持該生命週期,但是您可能會在相關鏈接文章中找到相關內容。注意:serveResource會 - 如果我沒有弄錯 - 生成一個p_p_lifecycle = 2參數,而本例使用p_p_lifecycle = 0(render)和p_p_state = exclusive。試試這個是否符合你的要求

但是,請考慮Marc B關於你的代碼的評論是不安全和太硬編碼的。基礎問題有更好的解決方案 - 例如Liferay提供文檔庫來開箱/下載文件。這並沒有這些問題。

+0

是的,就是這樣,我的文件也被打印出來,但是他被門戶代碼「覆蓋」了。這是另一種方式,但我的問題是,它不可能c從變量內容中刪除文件,然後在某個動作/事件中推送給客戶端? –

+0

是的,這就是所謂的「serveResource」(或「資源」)生命週期。你顯然使用「渲染」,它被設計爲嵌入在整個頁面,不能有任何內容類型比HTML不同(和,因此,只摘錄,不含,或。 –

+0

呀,而且是有可能使它與PHP的工作,或者我需要在Java中發展整個portlet嗎? –

0

如果您使用空格或任何其他字符開始PHP文件,標題將無法使用,並且顯示/下載將失敗。確保<?php標籤之前沒有任何東西。

除此之外,這應該工作(如果你沒有得到在瀏覽器中的錯誤)。

另一方面,如果您看到實際的PHP代碼,那麼您的服務器不支持PHP。

+0

我沒有看到實際的PHP代碼。並且我的服務器支持PHP的肯定。只是在我的download.php中可能的標題與整個門戶發送標頭混合? –

+0

這就是不太可能,如果你只是看到文件本身 - 你可以使用[Firebug for Firefox](http://getfirebug.com/)探索標籤,但確定...現在,你是什麼意思*「它將整個生成的HTML文件放入創建的文件中。」*? –

+0

好吧,我在這裏看到了html標籤,但不僅僅來自我的文件,而且來自整個門戶網站,但是我的php工作正常。在這裏支持,它看起來好像不是隻發送來自fread的回聲,但也是其他的東西 –