使用PHP下载存储在MySQL中的文件


Downloading files stored in MySQL using PHP

我在获取成功上传的文件时遇到了问题,这些文件位于MySQL数据库中名为appFiles的表中的blob字段中,无法返回并显示。我读了很多演示,大多数都很相似,但没有一个能解决我的问题。很久以前我做过一次,但那个旧项目的代码是用mysqli完成的,我想成为100%基于PDO的。这是我处理文件的代码部分:

} else if($ctoken === $utoken) {
    // Our tokens match, proceed with the view
    $stmt = $conn->prepare("SELECT fileMime, fileSize, fileName, file FROM $database.appFiles WHERE fileID = :fileid");
    $stmt->bindParam(':fileid', $_GET['fid'], PDO::PARAM_INT, 11);
    $stmt->execute();
    $fRes = $stmt->fetchAll();
    header('Content-Disposition: attachment; filename="' . $fRes[0][fileName] . '"');
    ob_clean();
    flush();
    echo $fRes[0][file];
    exit;
}

现在我知道数据正被成功地从数据库中选择出来。我可以通过执行var_dump($fRes)来轻松地检查这一点。它似乎都在那里,当然,它的大部分是二元混乱,在屏幕上毫无意义的许多其他混乱中,似乎大多是问号。

当我在PDF文档上测试它时,它只是在屏幕上弹出二进制文件。当我用DOC/DOCX文件测试它时,它至少会尝试在MS Word中打开它,但随后告诉我文件转换中断并显示了一个空文档(当显示DOCX时),或者显示了数百页的错误长文档(当尝试显示文档文件时)。

我已经尝试了一系列不同的标题选项,大多数都有不同的结果,没有一个是想要的。那么,我该如何让它以可理解的格式成功地吐出文件呢?

EDIT感谢Darren提供的以下链接,我现在使用它作为查看数据库中存储的文件的代码:

try {
    $stmt = $conn->prepare("SELECT * FROM $database.users WHERE uID = :uid");
    $stmt->bindParam(':uid', $uID, PDO::PARAM_INT, 11);
    $stmt->execute();
    $uRes = $stmt->fetchAll();
} catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
$ctoken = $_COOKIE['cookieToken'];
$utoken = $uRes[0]['sessionToken'];
if($ctoken !== $utoken) {
    // Our tokens don't match, kill the session
    header("Location: ./logOut.php");
    exit;
} else if($ctoken === $utoken) {
    // Our tokens match, proceed with the view
    $stmt = $conn->prepare("SELECT fileMime, fileSize, fileName, file FROM $database.appFiles WHERE fileID = :fileid");
    $stmt->bindParam(':fileid', $_GET['fid'], PDO::PARAM_INT, 11);
    $stmt->execute();
    $fRes = $stmt->fetchAll();
    header("Content-Type: application/octet-stream");
    header("Content-Transfer-Encoding: Binary");
    header("Content-disposition: attachment; filename='"".$fRes[0][fileName]."'"");
    echo readfile($fRes[0][file]);
    exit;
}

它们现在至少会提示我下载并保存它们,或者用正确的查看器打开它们。这太好了。然而,有些地方仍然非常错误,因为每次文件到达时只有0个字节。。。有人知道如何解决这个问题并最终使其正常工作吗?

第二版我对这种情况做了很多测试,发现从数据库中检索文件实际上根本没有问题。我的上传系统似乎有问题,文件在那里受到了某种程度的创伤。如果我使用phpmyadmin将上传的文件(名称、类型、大小等都正确导入)替换为原始文件,并将其"重新加载"到数据库中,那么下载界面就会根据需要完美地处理它。这里要学习的教训-不要仅仅因为文件的所有属性(如大小、mime、名称等)看起来都是正确的,就认为它是正确上传的!现在来了解我的上传为什么/在哪里把文件弄乱了。。。。如果您可能知道发生这种情况的地点或原因,请访问此处

只需更换

echo readfile($fRes[0][file]); 

通过

echo $fRes[0][file]; 

根据您的代码,字段file包含文件内容。因此,您只需echo即可。