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

Downloading files stored in MySQL using PHP

我无法让位于 MySQL 数据库中名为 appFiles 的 table 的 blob 字段中的已成功上传的文件返回并显示。我已经阅读了很多演示,大多数都是相似的,但 none 已经解决了我的问题。很久以前我做过一次,但是那个旧项目的代码是使用 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 文件时)。

我尝试了一系列不同的 header 选项,大多数结果不同,none 得到了我想要的结果。那么我如何让它成功地以可理解的格式吐出文件?

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

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 将上传的文件(名称、类型、大小等都正确导入)替换为原始文件 "reload" 将其上传到数据库中,然后根据下载的需要完美地处理它界面。在这里学习的教训 - 不要仅仅因为文件的所有属性(如大小、mime、名称等)看起来正确,就认为它已正确上传!现在发现 why/where 我的上传弄乱了文件....如果您知道发生这种情况的位置或原因,请 visit here

只需更换

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

echo $fRes[0][file]; 

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