如何在Ubuntu18.04上使用MySQLBLOB数据类型通过PHP存储图像
作为 Write for DOnations 计划的一部分,作者选择了 Girls Who Code 来接受捐赠。
介绍
Binary Large Object (BLOB) 是一种 MySQL 数据类型,可以存储图像、多媒体和 PDF 文件等二进制数据。
在创建需要紧密耦合数据库的应用程序时,其中图像应与相关数据同步(例如,员工门户、学生数据库或财务应用程序),您可能会发现存储学生护照等图像很方便MySQL 数据库中的照片和签名以及其他相关信息。
这就是 MySQL BLOB
数据类型的用武之地。 这种编程方法无需创建单独的文件系统来存储图像。 该方案还集中了数据库,使其更具可移植性和安全性,因为数据与文件系统隔离。 创建备份也更加无缝,因为您可以创建一个包含所有数据的 MySQL 转储 文件。
检索数据更快,并且在创建记录时,您可以确保维护数据验证规则和引用完整性,尤其是在使用 MySQL 事务 时。
在本教程中,您将使用 MySQL BLOB
数据类型在 Ubuntu 18.04 上使用 PHP 存储图像。
先决条件
要遵循本指南,您将需要以下内容:
- 使用带有 Ubuntu 18.04 的 初始服务器设置和具有
sudo
权限的非 root 用户配置的 Ubuntu 18.04 服务器。 - 按照 如何在 Ubuntu 18.04 上安装 Linux、Apache、MySQL、PHP (LAMP) 堆栈的指南设置 Apache、MySQL 和 PHP。 对于本教程,无需创建虚拟主机,因此您可以跳过第 4 步。
第 1 步 — 创建数据库
您将从为您的项目创建一个示例数据库开始。 为此,通过 SSH 连接到您的服务器,然后运行以下命令以 root 身份登录到您的 MySQL 服务器:
sudo mysql -u root -p
输入 MySQL 数据库的 root 密码,然后点击 ENTER
继续。
然后,运行以下命令来创建数据库。 在本教程中,我们将其命名为 test_company
:
CREATE DATABASE test_company;
创建数据库后,您将看到以下输出:
OutputQuery OK, 1 row affected (0.01 sec)
接下来,在 MySQL 服务器上创建一个 test_user
帐户,并记住将 PASSWORD
替换为强密码:
CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD';
您将看到以下输出:
OutputQuery OK, 0 rows affected (0.01 sec)
要授予 test_user
对 test_company
数据库的完全权限,请运行:
GRANT ALL PRIVILEGES ON test_company.* TO 'test_user'@'localhost';
确保获得以下输出:
OutputQuery OK, 0 rows affected (0.01 sec)
最后,刷新权限表以便 MySQL 重新加载权限:
FLUSH PRIVILEGES;
确保您看到以下输出:
OutputQuery OK, 0 rows affected (0.01 sec)
现在 test_company
数据库和 test_user
已准备就绪,您将继续创建用于存储示例产品的 products
表。 稍后您将使用此表插入和检索记录,以演示 MySQL BLOB
的工作原理。
从 MySQL 服务器注销:
QUIT;
然后,使用您创建的 test_user
的凭据再次登录:
mysql -u test_user -p
出现提示时,输入 test_user
的密码并点击 ENTER
继续。 接下来,通过键入以下内容切换到 test_company
数据库:
USE test_company;
选择 test_company
数据库后,MySQL 将显示:
OutputDatabase changed
接下来,通过运行创建一个 products
表:
CREATE TABLE `products` (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE, product_image BLOB) ENGINE = InnoDB;
此命令创建一个名为 products
的表。 该表有四列:
product_id
:此列使用BIGINT
数据类型以容纳最多 2⁶³-1 项的大型产品列表。 您已将该列标记为PRIMARY KEY
以唯一标识产品。 为了让 MySQL 处理插入列的新标识符的生成,您使用了关键字AUTO_INCREMENT
。product_name
:此列包含产品的名称。 您使用了VARCHAR
数据类型,因为该字段通常会处理最多50
字符的字母数字 -50
的限制只是用于本教程的目的。price
:出于演示目的,您的products
表包含price
列来存储产品的零售价。 由于某些产品可能具有浮动值(例如,23.69、45.36、102.99),因此您使用了DOUBLE
数据类型。product_image
:此列使用BLOB
数据类型来存储产品图像的实际二进制数据。
您已经为表使用了 InnoDB
存储 ENGINE
以支持广泛的功能,包括 MySQL 事务。 执行此操作以创建 products
表后,您将看到以下输出:
OutputQuery OK, 0 rows affected (0.03 sec)
从您的 MySQL 服务器注销:
QUIT;
您将获得以下输出
OutputBye
products
表现在已准备好存储包括产品图像在内的一些记录,您将在下一步中使用一些产品填充它。
第 2 步 — 创建用于连接和填充数据库的 PHP 脚本
在此步骤中,您将创建一个 PHP 脚本,该脚本将连接到您在步骤 1 中创建的 MySQL 数据库。 该脚本将准备三个示例产品并将它们插入到 products
表中。
要创建 PHP 代码,请使用文本编辑器打开一个新文件:
sudo nano /var/www/html/config.php
然后,在文件中输入以下信息,并将 PASSWORD
替换为您在步骤 1 中创建的 test_user
密码:
/var/www/html/config.php
<?php define('DB_NAME', 'test_company'); define('DB_USER', 'test_user'); define('DB_PASSWORD', 'PASSWORD'); define('DB_HOST', 'localhost'); $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
保存并关闭文件。
在此文件中,您使用了四个 PHP 常量连接到您在步骤 1 中创建的 MySQL 数据库:
DB_NAME
:该常量保存test_company
数据库的名称。DB_USER
:此变量保存test_user
用户名。DB_PASSWORD
:此常量存储test_user
帐户的 MySQLPASSWORD
。DB_HOST
:表示数据库所在的服务器。 在这种情况下,您使用的是localhost
服务器。
文件中的以下行启动 PHP Data Object (PDO) 并连接到 MySQL 数据库:
... $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD); ...
在文件末尾,您设置了几个 PDO 属性:
ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION
:此属性指示 PDO 抛出异常,该异常可被记录以用于调试目的。ATTR_EMULATE_PREPARES, false
:此选项通过告诉 MySQL 数据库引擎进行准备而不是 PDO 来提高安全性。
您将在接下来创建的两个 PHP 脚本中包含 /var/www/html/config.php
文件,分别用于插入和检索记录。
首先,创建 /var/www/html/insert_products.php
PHP 脚本,用于将记录插入到 products 表中:
sudo nano /var/www/html/insert_products.php
然后,将以下信息添加到 /var/www/html/insert_products.php
文件中:
/var/www/html/insert_products.php
<?php require_once 'config.php'; $products = []; $products[] = [ 'product_name' => 'VIRTUAL SERVERS', 'price' => 5, 'product_image' => file_get_contents("https://i.imgur.com/VEIKbp0.png") ]; $products[] = [ 'product_name' => 'MANAGED KUBERNETES', 'price' => 30, 'product_image' => file_get_contents("https://i.imgur.com/cCc9Gw9.png") ]; $products[] = [ 'product_name' => 'MySQL DATABASES', 'price' => 15, 'product_image' => file_get_contents("https://i.imgur.com/UYcHkKD.png" ) ]; $sql = "INSERT INTO products(product_name, price, product_image) VALUES (:product_name, :price, :product_image)"; foreach ($products as $product) { $stmt = $pdo->prepare($sql); $stmt->execute($product); } echo "Records inserted successfully";
保存并关闭文件。
在文件中,您在顶部包含了 config.php
文件。 这是您为定义数据库变量和连接到数据库而创建的第一个文件。 该文件还启动一个 PDO 对象并将其存储在 $pdo
变量中。
接下来,您创建了要插入数据库的产品数据数组。 除了 product_name
和 price
分别准备为字符串和数值之外,脚本使用 PHP 内置的 file_get_contents
函数从外部源读取图像并传递它们作为 product_image
列的字符串。
接下来,您准备了一条 SQL 语句并使用 PHP foreach{...}
语句将每个产品插入到数据库中。
要执行 /var/www/html/insert_products.php
文件,请使用以下 URL 在浏览器窗口中运行它。 请记住将 your-server-IP
替换为您服务器的公共 IP 地址:
http://your-server-IP/insert_products.php
执行文件后,您将在浏览器中看到一条成功消息,确认记录已插入数据库。
您已成功将包含产品图像的三条记录插入到 products
表中。 在下一步中,您将创建一个 PHP 脚本来检索这些记录并在浏览器中显示它们。
第 3 步 — 显示来自 MySQL 数据库的产品信息
有了数据库中的产品信息和图像,您现在将编写另一个 PHP 脚本,该脚本在浏览器的 HTML 表中查询和显示产品信息。
要创建文件,请键入以下内容:
sudo nano /var/www/html/display_products.php
然后,在文件中输入以下信息:
/var/www/html/display_products.php
<html> <title>Using BLOB and MySQL</title> <body> <?php require_once 'config.php'; $sql = "SELECT * FROM products"; $stmt = $pdo->prepare($sql); $stmt->execute(); ?> <table border = '1' align = 'center'> <caption>Products Database</caption> <tr> <th>Product Id</th> <th>Product Name</th> <th>Price</th> <th>Product Image</th> </tr> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo '<tr>'; echo '<td>' . $row['product_id'] . '</td>'; echo '<td>' . $row['product_name'] . '</td>'; echo '<td>' . $row['price'] . '</td>'; echo '<td>' . '<img src = "data:image/png;base64,' . base64_encode($row['product_image']) . '" width = "50px" height = "50px"/>' . '</td>'; echo '</tr>'; } ?> </table> </body> </html>
保存对文件的更改并关闭它。
在这里,您再次包含了 config.php
文件以连接到数据库。 然后,您已经准备并使用 PDO 执行了一条 SQL 语句,以使用 SELECT * FROM products
命令从 products
表中检索所有项目。
接下来,您创建了一个 HTML 表,并使用 PHP while() {...}
语句将产品数据填充到其中。 $row = $stmt->fetch(PDO::FETCH_ASSOC)
行查询数据库并将结果作为多维数组存储在 $row
变量中,然后使用 $row['column_name']
语法将其显示在 HTML 表格列中.
product_image
列中的图像包含在 <img src = "">
标记内。 您已使用 width
和 height
属性将图像调整为更小的尺寸以适合 HTML 表格列。
为了将 BLOB
数据类型保存的数据转换回图像,您使用了内置的 PHP base64_encode
函数和 Data URI 方案的以下语法[ X177X]:
data:media_type;base64, base_64_encoded_data
在这种情况下,image/png
是 media_type
,来自 product_image
列的 Base64
编码字符串是 base_64_encoded_data
。
接下来,在网络浏览器中输入以下地址,执行 display_products.php
文件:
http://your-server-IP/display_products.php
在浏览器中运行 display_products.php
文件后,您将看到一个 HTML 表格,其中包含产品列表和相关图像。
这证实了用于从 MySQL 检索图像的 PHP 脚本按预期工作。
结论
在本指南中,您使用 MySQL BLOB
数据类型在 Ubuntu 18.04 上使用 PHP 存储和显示图像。 您还看到了将图像存储在数据库中而不是将它们存储在文件系统中的基本优势。 这些包括便携性、安全性和易于备份。 如果您正在构建需要将信息和相关图像存储在一起的应用程序(例如学生门户网站或员工数据库),那么这项技术对您很有用。
有关 MySQL 中支持的数据类型的更多信息,请遵循 MySQL 数据类型指南 。 如果您对有关 MySQL 和 PHP 的更多内容感兴趣,请查看以下教程: