如何使用PHP从MySQL数据库存储和检索图像?

66
我该如何在MySQL中插入图片,然后使用PHP检索它?
我对这两个领域的经验有限,所以我需要一些代码来帮助我开始解决这个问题。

4
我建议您在仔细考虑后,选择将图像存储在文件系统中,而不是数据库中。请参见此处:https://dev59.com/OnVD5IYBdhLWcg3wXaYd - Scott Evernden
8个回答

122

首先,您需要创建一个存储图像的MySQL表,例如:

create table testblob (
    image_id        tinyint(3)  not null default '0',
    image_type      varchar(25) not null default '',
    image           blob        not null,
    image_size      varchar(25) not null default '',
    image_ctgy      varchar(25) not null default '',
    image_name      varchar(50) not null default ''
);

然后你可以像这样将图片写入数据库:

/***
 * All of the below MySQL_ commands can be easily
 * translated to MySQLi_ with the additions as commented
 ***/ 
$imgData = file_get_contents($filename);
$size = getimagesize($filename);
mysql_connect("localhost", "$username", "$password");
mysql_select_db ("$dbname");
// mysqli 
// $link = mysqli_connect("localhost", $username, $password,$dbname); 
$sql = sprintf("INSERT INTO testblob
    (image_type, image, image_size, image_name)
    VALUES
    ('%s', '%s', '%d', '%s')",
    /***
     * For all mysqli_ functions below, the syntax is:
     * mysqli_whartever($link, $functionContents); 
     ***/
    mysql_real_escape_string($size['mime']),
    mysql_real_escape_string($imgData),
    $size[3],
    mysql_real_escape_string($_FILES['userfile']['name'])
    );
mysql_query($sql);

你可以使用以下代码在网页中显示数据库中的图片:

$link = mysql_connect("localhost", "username", "password");
mysql_select_db("testblob");
$sql = "SELECT image FROM testblob WHERE image_id=0";
$result = mysql_query("$sql");
header("Content-type: image/jpeg");
echo mysql_result($result, 0);
mysql_close($link);

4
如果您的图像大小超过65K,您需要更改blob字段的类型。https://dev59.com/5XA75IYBdhLWcg3wDUYo - Giles Roberts
如果图像数据包含撇号,那么似乎这将会失败得非常惨。 - Ry-
@minitech:甚至是图像名称...现在添加了mysql_real_escape_string - Andomar
如果图片类型是gif或者除jpeg以外的其他类型,应该怎么处理? - Md. Sahadat Hossain
1
@KrLx_roller:将图像存储在服务器文件夹中可能更好,但这不是OP所问的。因此,我认为这个问题是“有用的”。+! - J. Allan
显示剩余4条评论

25

不要将图片存储在数据库中,而是将它们存储在硬盘的文件夹中,并将它们的位置存储在数据库中。


1
你在做假设。现在拥有一个基于Web/浏览器的应用程序并希望在离线模式下运行非常普遍,因此您需要一些聪明的缓存管理和/或将图像存储在基于Web的数据库中(WebSQL、PouchDB、Couchbase、Mongo等)。 - ekerner
1
这个答案声称是一个更好的解决方案;OP想要将图像存储在数据库中。 - Robert Simpson
1
主观且与如何将图像插入数据库的问题无关。 - user5175034

12

请注意,从数据库中提供图像通常比从磁盘提供图像要慢得多。

你需要启动 PHP 进程,打开数据库连接,让数据库从与文件系统相同的磁盘和缓存 RAM 中读取图像数据,通过几个套接字和缓冲区传输数据,然后再通过 PHP 推送出去。而 PHP 默认情况下会使它不可缓存并添加分块 HTTP 编码的开销。

相比之下,现代 Web 服务器可以通过只进行少量优化的内核调用(内存映射文件和将这个内存区域传递给 TCP 栈),仅服务于那些无需复制内存且几乎没有任何开销的图片。

这就是一台机器能够同时服务于20张或2000张图像的差别。

所以,不要这样做,除非你绝对需要事务完整性(实际上,即使是这种情况,只用图像元数据在数据库中,还有文件系统清理例程也可以完成),并知道如何改善 PHP 的 HTTP 处理方式以适合图片。


8
我的观点是,与其直接将图像存储到数据库中,建议在数据库中存储图像位置。比较两种选项,将图像存储在数据库中对于安全目的来说更加安全。缺点是:
  1. 如果数据库损坏,无法检索。
  2. 与其他选项相比,从数据库检索图像文件速度较慢。
另一方面,在数据库中存储图像文件位置将具有以下优点。
  1. 易于检索。
  2. 如果存储多个图像,我们可以轻松检索图像信息。

7

7

个人建议不要将图片存储在数据库中,可以将其放入一个无法从外部访问的文件夹中,并使用数据库来跟踪其位置。这样可以使数据库大小保持较小,并且可以通过使用PHP来包含它。这样就没有办法在没有PHP的情况下访问该图片。


0

我认同 @Andomar 的基本概念,但为了避免在 SQL 中存储大量数据,应将实际图像存储在磁盘上。请记住,在 SQL 中,一个大字段是 255 个字符。因此,您需要将图像文件存储为 Blob,这在您只有少量行(想象一下:数百行而不是数百万行)时效果很好。这个推断很复杂,但这是个好习惯。我是这么知道的:

我写了一个大型项目,存储了很多(很多)图像。总是将它们保存在磁盘上,以避免 SQL 的麻烦。如果您担心数据库损坏会让您无法将图像“重建”到数据库中,那么有一个简单的解决方法(除了备份 SQL 表格)

使用有意义的目录名称和解析,将图像存储在目录树中。例如,按时间存储可能看起来像“/year/month/day/picture.jpg”,按用户存储可能看起来像“/user_id/picture.jpg”。将其作为概念,并仅在 SQL 中存储路径。这将使您的 SQL 表格变得小而经常可缓存,并允许您的 SQL 表格位于一个服务器上,而您的图像则存储在另一个“服务器”上,例如 AWS 的 S3。

如果你真的很担心,你可以在与图像本身相同的目录中存储一个名为“{image_name)_meta.json”的文件。将其中填充有关于图像的元数据,这些元数据通常存储在数据库表中。如果表损坏了,你可以编写一个小函数来遍历树并从JSON文件重建表格。当然,这会占用更多的磁盘空间,但它非常便宜(想想:AWS的S3)。
有很多解决方法,但是在任何SQL类型的表中存储大量图像很少是一个好主意。例外情况可能是同时显示数百个图像,或者也许是快速检索时间(而不是亚秒级别)。
祝你的项目好运!

0

不要将图像存储在数据库中,而是将其存储在手机和电脑中,并仅使用其路径,这将节省您的数据库空间。


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Simas Joneliunas

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