在 Web 上显示来自 MySQL 的数据:简介
以下文章摘自 PHP 和 MySQL:从新手到忍者,第 7 版,这是学习构建专业 Web 应用程序所需的所有工具、原则和技术的实践指南。 在本系列的最后一个教程中,您将学习如何获取存储在 MySQL 数据库中的信息并将其显示在网页上以供所有人查看。
- 使用 Docker 设置 PHP 开发环境 PHP 初学者指南 MySQL 简介:初学者指南 在 Web 上显示来自 MySQL 的数据:简介
就是这样——你注册的东西! 在本章中,您将学习如何获取存储在 MySQL 数据库中的信息并将其显示在网页上以供所有人查看。
到目前为止,您已经编写了第一个 PHP 代码并学习了 MySQL(一种关系数据库引擎)和 PHP(一种服务器端脚本语言)的基础知识。
现在您已准备好学习如何结合使用这些工具来创建一个网站,用户可以在其中查看数据库中的数据,甚至可以添加自己的数据。
注意:与第 3 章一样,我在这里使用“MySQL”来指代数据库协议。 您的 PHP 脚本也会这样做。 本章中以及您将编写的 PHP 代码中有很多对“MySQL”的引用,即使我们实际上是在连接到 MariaDB 数据库。
大局观
在我们向前迈进之前,为了清楚地了解我们的最终目标,值得退后一步。 我们有两个强大的工具可供使用:PHP 脚本语言和 MySQL 数据库引擎。 重要的是要了解这些将如何组合在一起。
在我们的网站上使用 MySQL 的目的是允许从数据库中动态提取内容以创建网页以在常规浏览器中查看。 因此,在系统的一端,您的站点访问者使用 Web 浏览器请求页面。 该浏览器希望收到一个标准的 HTML 文档作为回报。 在另一端,您拥有站点的内容,这些内容位于 MySQL 数据库的一个或多个表中,该数据库只了解如何响应 SQL 查询(命令)。
如上图所示,PHP 脚本语言是两种语言的中间人。 它处理页面请求并使用 SQL 查询从 MySQL 数据库中获取数据,就像您在第 3 章中用来创建笑话表的那些查询一样。然后它动态地将其吐出为浏览器期望的格式良好的 HTML 页面。
为了让您头脑清晰,当有访问者访问您网站上的页面时,会发生这种情况:
- 访问者的网络浏览器从您的网络服务器请求网页。 Web 服务器软件(通常是 Apache 或 NGINX)识别出请求的文件是 PHP 脚本,因此服务器启动 PHP 解释器来执行文件中包含的代码。 某些PHP命令(这将是本章的重点)连接到MySQL数据库并请求属于网页的内容。 MySQL 数据库通过将请求的内容发送到 PHP 脚本来做出响应。 PHP 脚本将内容存储到一个或多个 PHP 变量中,然后使用
echo
将内容作为网页的一部分输出的语句。 PHP 解释器通过将它创建的 HTML 副本交给 Web 服务器来完成。 Web 服务器将 HTML 发送到 Web 浏览器,就像发送纯 HTML 文件一样,只是页面不是直接来自 HTML 文件,而是 PHP 解释器提供的输出。 然而,浏览器无法知道这一点。 就浏览器而言,它请求和接收网页与其他任何网页一样。
创建 MySQL 用户帐户
为了让 PHP 连接到您的 MySQL 数据库服务器,它需要使用用户名和密码。 到目前为止,您的笑话数据库所包含的只是一些精辟的妙语,但不久之后它可能会包含敏感信息,例如电子邮件地址和有关您网站用户的其他私人详细信息。 出于这个原因,MySQL 被设计得非常安全,让您可以严格控制它将接受哪些连接以及允许这些连接做什么。
在第 3 章中,Docker 环境已经包含一个 MySQL 用户,您已经使用它来登录 MySQL 服务器。
您可以使用相同的用户名从 PHP 脚本连接到数据库(v.je
) 和密码 (v.je
),但创建一个新帐户很有用——因为如果您有网络服务器,您可能想用它来托管多个网站。 通过为每个网站提供自己的用户帐户,您可以更好地控制谁有权访问任何给定网站的数据。 如果您正在与其他开发人员合作,您可以授予他们访问他们正在开发的站点的权限,但仅此而已。
您应该创建一个新的用户帐户,该帐户仅具有在 ijdb
您的网站所依赖的数据库。 让我们现在就这样做。
要创建用户,请打开 MySQL Workbench 并连接到您的服务器。 然后运行以下查询:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword';
GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
第一个查询是不言自明的:它创建了一个名为 ijdbuser
用密码 mypassword
. 这 %
用户名后的符号表示可以从任何位置连接到数据库。 第二个查询为用户提供了对 ijdb
架构,因此该用户可以查看和修改该架构中的所有表、列和数据 ijdb
模式,但无法访问它之外的任何内容。
现在用户 ijdbuser
已经创建好了,我们就可以用它来连接数据库了。 可以与该用户在 MySQL Workbench 中建立连接,但由于权限有限,最好让 MySQL Workbench 使用 v.je
帐户。 相反,我们将在从 PHP 脚本连接时使用新用户。
使用 PHP 连接到 MySQL
在从 MySQL 数据库中检索内容以包含在网页中之前,您必须知道如何从 PHP 脚本内部建立到 MySQL 的连接。 到目前为止,您已经使用了一个名为 MySQL Workbench 的应用程序来连接到您的数据库。 正如 MySQL Workbench 可以直接连接到正在运行的 MySQL 服务器一样,您自己的 PHP 脚本也可以。
尽管本章完全讨论从 PHP 连接到 MySQL,但实际上我们连接的是上一章讨论的 MariaDB 数据库。 PHP 看不出 MySQL 和 MariaDB 之间有任何区别,因为它们可以互换。 我将在整个过程中将数据库称为 MySQL,因为所有使用的命令都可用于连接到 MySQL 或 MariaDB 数据库服务器。
最初的 MySQL 数据库为 MySQL Workbench 和 PHP 等客户端与服务器通信提供了一种标准化的方法。 MariaDB 复制了那个标准,并且 PHP 中的所有命令都使用 MySQL 这个名称,所以为了简单起见,我将在本章中使用术语 MySQL 来指代数据库。
从 PHP 连接到 MySQL 服务器有三种方法:
- MySQL 库 MySQLi 库 PDO 库
这些基本上都做同样的工作——连接到数据库并向它发送查询——但它们使用不同的代码来实现它。
MySQL 库是最古老的连接数据库的方法,在 PHP 2.0 中引入。 它包含的功能很少,并且从 PHP 5.0(2004 年发布)开始被 MySQLi 取代。
使用旧的 MySQL 库连接和查询数据库,函数如 mysql_connect()
和 mysql_query()
被使用。 自 PHP 5.5 起,这些函数已被弃用——意味着应避免使用它们,并且自 PHP 7.0 起已完全从 PHP 中删除。
尽管大多数开发人员在 PHP 5.0 发布后就看到了更改的原因,但是 Web 上仍然有数百篇文章和代码示例使用这些现在不存在的 mysql_*
功能——尽管事实上 MySQLi 十五年来一直是首选库。
如果您遇到包含该行的代码示例 mysql_connect()
, 检查文章的日期。 它可能是从 2000 年代初期开始的,在编程中,您永远不应该相信那么古老的东西。 事情总是在变化——这就是本书出版第七版的原因!
在 PHP 5.0 中,发布了 MySQLi 库——代表“MySQL Improved”——以解决原始 MySQL 库中的一些限制。 你可以很容易地识别出MySQLi的使用,因为代码会使用诸如 mysqli_connect()
和 mysqli_query()
.
在 PHP 5.0 中的 MySQLi 库发布后不久,PHP 5.1 发布了,其中有大量更改帮助塑造了我们今天编写 PHP 的方式(主要与面向对象编程有关,稍后您会看到很多)在本书中)。 PHP 5.1 的主要变化之一是它引入了第三个库 PDO(PHP 数据对象),用于连接到 MySQL 数据库。
PDO 和 MySQLi 之间有几个不同之处,但主要的一个是您可以使用 PDO 库连接到几乎任何数据库服务器——例如 Oracle 服务器或 Microsoft SQL Server。 对于开发人员来说,这种通用方法的最大优势在于,一旦您学会了如何使用该库与 MySQL 数据库进行交互,与另一个数据库服务器进行交互就非常简单。
可以说,为 PDO 编写代码更简单,并且有一些细微差别可以使 PDO 代码更具可读性——准备好的语句中的命名参数是主要好处。 (别担心,我稍后会解释这意味着什么。)
由于这些原因,最近的 PHP 项目都使用 PDO 库,我将在本书中向您展示如何使用该库。 有关差异的更多信息,请查看 SitePoint 文章“重新引入 PDO – 在 PHP 中访问数据库的正确方法”。
在那堂小小的历史课之后,您可能急切地想重新开始编写代码。 以下是如何使用 PDO 建立与 MySQL 服务器的连接:
new PDO('mysql:host=hostname;dbname=database', 'username',
'password')
现在,想想 new PDO
作为内置函数,就像 rand
我们在第 2 章中使用过的函数。如果你在想“嘿,函数的名称中不能有空格!”,那你比一般的熊聪明,我稍后会解释这里到底发生了什么。 无论如何,它需要三个参数:
- 指定数据库类型的字符串 (
mysql:
), 服务器的主机名 (host=hostname;
), 和数据库的名称 (dbname=database
) 您希望 PHP 使用该用户名的 MySQL 密码的 MySQL 用户名
您可能还记得第 2 章中提到的 PHP 函数通常在被调用时返回一个值。 这 new PDO
“函数”返回一个名为 a 的值 PDO
标识已建立的连接的对象。 由于我们打算使用连接,因此我们应该通过将其存储在变量中来保留该值。 这是它的样子,填充了必要的值以连接到您的数据库:
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser',
'mypassword');
您可能会看到最后两个参数发生了什么:它们是您在本章前面创建的用户名和密码。
第一个参数有点复杂。 这 dbname=ijdb
部分告诉 PDO 使用名为 ijdb
. 从 PHP 运行的任何查询都将默认为该模式中的表。 SELECT * FROM joke
将从中选择记录 joke
中的表 ijdb
模式。
即使您已经熟悉 PHP、PDO 和 MySQL, host=mysql
部分看起来很混乱。 通常,这将是 host=localhost
(指本地计算机,运行PHP的同一台机器)或指向托管数据库的特定域名,例如 host=sitepoint.com
.
为什么 host=mysql
,什么是 mysql
指的是这里? 在 Docker 中,每个服务都有一个名称。 如果你检查 docker-compose.yml
配置服务器的文件,调用数据库服务 mysql
,并且在 Docker 中,一个服务可以使用另一个服务的名称连接到另一个服务。
撇开争论不谈,这里重要的是要看到返回的值 new PDO
存储在一个名为 $pdo
.
MySQL 服务器是一个完全独立于 Web 服务器的软件。 因此,我们必须考虑可能由于网络中断导致服务器不可用或无法访问,或者因为您提供的用户名/密码组合被服务器拒绝,或者因为您只是忘记启动您的 MySQL 服务器! 在这种情况下, new PDO
不会运行,并会抛出 PHP 异常。
注意:至少在默认情况下,PHP 可以配置为不抛出异常并且不会连接。 这通常不是理想的行为,因为它使找出问题所在变得更加困难。
如果您想知道“抛出一个 PHP…”是什么意思