PHP readfile()破坏了文件

时间:2014-03-05 23:44:11

标签: php header readfile corrupt

在我的函数中,我正在下载一个将下载保存到日志文件的文件。每当我尝试下载上传的Excel文件时,Excel都会声明它已损坏。我的本地副本工作正常。这是我的download.php:

<?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; ?>

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:13)

想出来。我只是在ob_get_clean();readfile();之后添加了ob_end_flush();

答案 1 :(得分:10)

请记住,您可以拥有嵌套的输出缓冲区,这也会破坏您的下载(欢迎Vladamir为此搞清楚)。因此,要完全清除输出缓冲区(而不是仅运行ob_end_clean();),请在读取文件之前运行此命令:

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

这将清除整个缓冲区,你不会有任何额外的字符来搞乱下载。

答案 2 :(得分:0)

我也有同样的情况:在我的功能中,我正在下载PDF文件,文件总是下载损坏,我花了几个小时傻笑,没有任何帮助,最后:

我必须添加die();exit();作为最后一行,因为我使用的是MVC框架,并且MVC导致在操作完成后呈现视图。

底线:确保在最后一行readfile(FILE_NAME)之后没有执行任何代码