【发布时间】:2015-04-07 04:47:52
【问题描述】:
我无法让我成功上传的文件位于我的 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 时)或显示一个不正确的长文档和 gobblygook 混乱数百页(尝试显示 doc 文件时)。
我已经尝试了一系列不同的标题选项,大多数结果不同,没有一个符合预期。那么如何让它以可理解的格式成功吐出文件呢?
编辑感谢 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、名称等)看起来都正确,就认为它是正确上传的!现在来了解我的上传文件为何/在哪里弄乱了文件……如果您知道发生这种情况的位置或原因,请visit here
【问题讨论】:
-
您可能需要阅读this,其中概述了如何强制下载。
-
file列包含什么?如果是文件内容,那么您只需回显它。如果它是文件的路径,那么您只需调用readfile(不带回显)。 -
你好海纳。文件本身作为介质 blob 存储在 MySQL 数据库中,并且不存储在目录中的任何位置。所以它是从 MySQL PDO 请求中提取的数据的一部分,而 $fRes[0][file] 是(应该是)文件本身。
-
我把最后一行从 - echo readfile($fRes[0][file]); - 成为 - echo $fRes[0][file];但结果是一样的。它的大小为 1 个字节,比以前多 1 个字节,但肯定无法使用,而且比它应该的要少得多......!