2014-03-05 95 views
4

在我的函數中,我正在下載一個文件,將下載文件保存到日誌文件中。每當我嘗試下載我上傳的Excel文件時,Excel都會聲明它已損壞。我的本地副本工作正常。這是我的download.php:PHP readfile()破壞文件

<?php 
include_once 'includes/db_connect.php'; 
include_once 'includes/functions.php'; 

sec_session_start(); 
ob_start(); 
?> 

<?php if (login_check($mysqli) == true) :?> 
<?php 
$logFile = "download.log"; 
$directory = "./downloads/"; 
date_default_timezone_set('America/New_York'); 

$filename = $_GET['file']; 
$path = "$directory$filename"; 
if(file_exists($path) AND substr_count($filename,"/") == "0") { 
    if (isset($logFile)) { 
    $downloadLogRecord = $filename." || ".$_SESSION['name']." || ".$_SESSION['username']." || ".$_SERVER['REMOTE_ADDR']." || ".date('Y-m-d H:i:s')."\r\n"; 
    @file_put_contents($logFile,$downloadLogRecord,FILE_APPEND|LOCK_EX); 
    } 
    header("Content-type: application/octet-stream"); 
    header("Content-Disposition: attachment; filename=$filename"); 
    header("Content-Length: ".filesize($path)); 
    readfile("$path"); 
} 
?> 
<?php else : ?> 
    <p> 
    <span class="error">You are not authorized to access this page.</span> Please <a href="index.php">login</a>. 
    </p> 
<?php endif; ?> 

我該如何解決這個問題?

+1

你ob_start會緩衝輸出;但除非您在某個時間點刷新緩衝區,否則在腳本終止導致損壞時''>''和'<?php'之間的空白仍會被注入到文件中 –

回答

12

想通了。我只是在readfile();ob_end_flush();之前加了ob_get_clean();之後。

+0

謝謝!在所有提供的解決方案中,這是解決了我的問題的解決方案,其中服務器端腳本將在從本地主機提交時傳遞損壞的文件,我的腳本正常工作。 你拼命搜索不必要的linebreaks並嘗試大量的計算器答案後,你創造了很大的緩解!真的非常感謝你 – Max

+0

我遲到了,但就像@Max說的 - 這也解決了我的問題! :) – prk

7

請記住,你可以有嵌套的輸出緩衝區,這也會破壞你的下載(爲了解決這個問題,歡呼聲Vladamir)。所以,徹底清除輸出緩衝(而不是隻是運行ob_end_clean();),你讀你的文件之前運行此:

while (ob_get_level()) { 
    ob_end_clean(); 
} 

這將清除出你的整個緩衝區,你不會有任何額外的字符弄亂你下載。

+1

我花了數小時尋找我的zip檔案下載爲腐敗的原因。上帝保佑你,先生:) –

+0

你是最受歡迎的。隨時加入,讓其他人更容易看到它。 – Maximus

+0

小時,在這裏度過了一段歡樂時光,我可以做的只是謝謝你 – Fanckush

0

我也有同樣的情況:在我的功能,我下載一個PDF文件,該文件總是時下載損壞,我花了幾個小時傻笑周圍,沒有任何幫助,終於:

我不得不添加die();exit();作爲最後一行,因爲我使用的是MVC框架,並且MVC在操作完成後導致呈現視圖。

底線:確保你沒有在最後一行後執行任何代碼readfile(FILE_NAME)