如何在PHP中从MySQL数据库下载基于blob的文件?

3

如何编写一个PHP脚本,使我能够从MySQL数据库中下载文件。 我有一个名为files的表,上传的文件保存在基于BLOB的字段中。

+-------+----------+----------+------------+-------------------+--------+
|fileID | fileName | fileType | fileSize   |fileData           | userID |
+-------+----------+----------+------------+-------------------+--------+
| 1     | file1    | JPEG     | 211258     |[BLOB - 206.3 KiB] | 1      |
| 2     | file2    | PNG      | 211258     |[BLOB - 201.3 KiB] | 1      |
+-------+----------+----------+------------+-------------------+--------+

我无法找到一种方法来调用文件进行下载,每次尝试时,我都会得到二进制数据,例如随机数字和符号。

我尝试了通过参数(fileID、fileName、fileType)传递到 download.php 页面的查询:

$id = mysqli_real_escape_string($link, $_GET['fileID']);
$name = mysqli_real_escape_string($link, $_GET['fileName']);
$type = mysqli_real_escape_string($link, $_GET['fileType']);

$SELECT = "SELECT * FROM files WHERE fileID = $id AND fileName = $name ";
$result = mysqli_query($SELECT, $link);
$result = mysqli_fetch_assoc($result);

header("Content-type: $type");  
echo $result['fileData'];

但这会导致页面空白,没有输出。
如何将文件1下载为JPEG文件保存到我的硬盘?

1
不将文件存储在数据库中的一个很好的理由。 - user557846
@Dagon 那我应该把它们存储在哪里呢? - user1386999
1
Content-type 应该是 image/jpeg,这可能会解决你遇到的问题。老实说,你应该将图片的路径存储在数据库中,而不是将它们存储为二进制大对象。 - elitechief21
1
文件应存储在文件系统中。 - user557846
你可以使用application/octet-stream作为Content-type,但这种方式不好使用,因为你不知道你正在下载的文件类型。你可以将文件类型存储为image/jpegimage/pngapplication/zip等,并保持你的代码不变。 - elitechief21
显示剩余2条评论
2个回答

12

这是处理 blob 文件时遇到的最常见问题。从您的示例中,我可以看到您将“fileType”保存为文件的扩展名(即图像的'jpg',pdf 文件的'pdf'等)。但是,您可以将文件类型保存为 MIME 内容类型,而不是这样。

假设您上传了一个 jpeg 图像- MIME 类型将存储在“fileType”中,如“image/jpeg”。同理,对于 pdf 文件,它将存储为“application/pdf”。我设计了这样的代码来从数据库下载 blob 文件。我假设文件已经上传到您创建的数据库表中。

数据库表“uploads”

| fileID | fileName | fileType | fileSize |fileData | userID |

download.php

<?php
$connection =  mysqli_connect("localhost","root"," ",your_database);

$id = 1;

$query = "SELECT * FROM uploads WHERE userID = ?";
$result = $connection->execute_query($query, [$id]); 
list($id, $file, $type, $size, $content) = mysqli_fetch_array($result);
header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$file");
echo $content;

您可以在此处找到blob-upload的完整代码这里

这个方案在从HTML转向PHP并强制下载时运行良好,但是在使用jQuery和PHP时则不起作用。内容被输出到控制台,但没有文件被下载! - tmzafar
1
@tmzafar没错,这就是AJAX的工作原理——响应返回到JavaScript。不要指望通过Ajax下载文件。 - ADyson

-1
你可以使用会话和提交文件名和文件内容到下载页面。
session_start();
$_SESSION['filename'] = $filename
$_SESSION['file'] = $file
<a href="download.php">echo "Download File"</a>

在download.php中使用以下代码。
session_start();
$filename = $_SESSION['filename'];
$file = $_SESSION['file'];
header("Content-Disposition: attachment; filename=$filename");
ob_clean();
flush();
echo $file;

这与会话变量无关,而与 MIME 类型有关。 - Sanket Deshpande

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接