2014-03-05 44 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)