下面的文章摘自《PHP和MySQL。新手到忍者,第7版》的节选,这是一本学习使用PHP和MySQL构建专业Web应用程序所需的所有工具、原理和技术的实践指南。在本系列的最后一个教程中,你将学习如何将存储在MySQL数据库中的信息,显示在网页上供大家观看。
- 服务器设置和安装
- PHP初学者指南
- 介绍MySQL。初学者指南
- 在网络上显示来自MySQL的数据:简介
这就是--你报名参加的东西在这一章中,你将学习如何将存储在MySQL数据库中的信息,显示在网页上供大家观看。
到目前为止,你已经写了第一段PHP代码,并了解了MySQL(一种关系型数据库引擎)和PHP(一种服务器端脚本语言)的基本知识。
现在你已经准备好学习如何共同使用这些工具来创建一个网站,让用户可以查看数据库中的数据,甚至添加自己的数据。
注意:和第三章一样,我在这里用 "MySQL "来指代数据库协议。你的PHP脚本也会这样做。在本章中,以及在你将要写的PHP代码中,有许多地方提到了 "MySQL",尽管我们实际上是在连接一个MariaDB数据库。
大局观
在我们向前跃进之前,值得回头看看我们的最终目标。我们有两个强大的工具可以使用:PHP脚本语言和MySQL数据库引擎。重要的是要了解这些将如何结合在一起。
在我们的网站上使用MySQL的目的是允许从数据库中动态地提取内容,以创建在普通浏览器中查看的网页。因此,在系统的一端,你有一个使用网络浏览器访问你的网站的访客来请求一个页面。该浏览器希望收到一个标准的HTML文档作为回报。在另一端,你有你网站的内容,它位于MySQL数据库中的一个或多个表中,该数据库只了解如何响应SQL查询(命令)。
如上图所示,PHP脚本语言是两种语言的中间人。它处理页面请求,并使用SQL查询从MySQL数据库中获取数据,就像你在第三章中用来创建笑话表的那些查询。然后,它将数据动态地吐出,成为浏览器所期望的格式良好的HTML页面。
为了让你记忆清晰,这就是当有访客访问你的网站页面时所发生的事情。
-
访客的网络浏览器从你的网络服务器上请求该网页。
-
web服务器软件(通常是Apache或NGINX)识别出请求的文件是一个PHP脚本,所以服务器启动了PHP解释器来执行文件中的代码。
-
某些PHP命令(这将是本章的重点)连接到MySQL数据库并请求属于网页中的内容。
-
MySQL数据库通过向PHP脚本发送所请求的内容来作出回应。
-
PHP脚本将内容存储到一个或多个PHP变量中,然后使用
echo语句将内容作为网页的一部分输出。 -
PHP解释器最后将它所创建的HTML的副本交给Web服务器。
-
web 服务器像发送普通的 HTML 文件一样将 HTML 发送给 web 浏览器,只不过这个页面不是直接来自 HTML 文件,而是由 PHP 解释器提供的输出。然而,浏览器没有办法知道这一点。就浏览器而言,它是在像其他网页一样请求和接收一个网页。
创建一个MySQL用户帐户
为了让 PHP 连接到你的 MySQL 数据库服务器,它需要使用一个用户名和密码。到目前为止,你的笑话数据库所包含的只是一些精辟的格言,但过不了多久,它就可能包含敏感信息,如电子邮件地址和其他关于你的网站用户的私人细节。出于这个原因,MySQL被设计得非常安全,让你严格控制它将接受哪些连接以及这些连接被允许做什么。
Docker环境在第三章中已经包含了一个MySQL用户,你已经用它来登录MySQL服务器。
你可以使用相同的用户名(v.je)和密码(v.je)从你的PHP脚本连接到数据库,但创建一个新的账户是很有用的--因为如果你有一个Web服务器,你可能想用它来托管一个以上的网站。通过给每个网站提供自己的用户账户,你将有更多的机会控制谁可以访问任何特定网站的数据。如果你和其他开发人员一起工作,你可以给他们访问他们正在工作的网站的权限,但不能再多了。
你应该创建一个新的用户账户,只拥有它在你的网站所依赖的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发布后就看到了这种变化的原因,但网络上仍有数百篇文章和代码实例在使用这些已经不存在的mysql_* 函数--尽管事实上MySQLi已经有效地成为了15年的首选库。
如果你遇到一个包含行mysql_connect() 的代码例子,请检查文章的日期。它可能是21世纪初的,而在编程中,你永远不应该相信那么老的东西。事情一直在变化--这就是为什么这本书已经是第七版了
在PHP 5.0中,MySQLi库--代表 "MySQL改进版"--被发布以解决原始MySQL库中的一些限制。你可以很容易地识别出MySQLi的使用,因为代码中会用到mysqli_connect() 和mysqli_query() 等函数。
在PHP 5.0中的MySQLi库发布后不久,PHP 5.1发布了,其中有大量的变化,有助于塑造我们今天的PHP编写方式(主要与面向对象的编程有关,在本书后面你会看到很多)。PHP 5.1的主要变化之一是引入了第三个库,PDO(PHP Data Objects),用于连接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 函数一样。如果你在想 "嘿,函数的名字里不能有空格!",你比一般的熊聪明,我一会儿就会解释这里到底是怎么回事。在任何情况下,它需要三个参数。
- 一个指定数据库类型的字符串(
mysql:),服务器的主机名(host=hostname;),以及数据库的名称(dbname=database)。 - 你希望 PHP 使用的 MySQL 用户名
- 该用户名的MySQL密码
你可能还记得第二章,PHP函数在被调用时通常会返回一个值。这个new PDO "函数 "返回一个叫做PDO 对象的值,用来标识已经建立的连接。由于我们打算使用这个连接,我们应该把这个值储存在一个变量中。下面是它的样子,填入必要的值以连接到你的数据库。
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser',
'mypassword');
你也许能看出最后两个参数是怎么回事:它们是你在本章前面创建的用户名和密码。
第一个参数就比较复杂了。dbname=ijdb 部分告诉PDO使用名为ijdb 的数据库(也被称为模式)。任何从PHP运行的查询都会默认为使用该模式下的表。SELECT * FROM joke 将从ijdb 模式下的joke 表中选择记录。
即使你已经熟悉了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异常 "是什么意思,请准备好!你将会发现更多的问题。你将会发现PHP语言的更多特性。
PHP异常是指当你告诉 PHP 执行一项任务而它无法完成时的情况。PHP 将尝试做它被告知的事情,但会失败;为了告诉你这个失败,它将向你抛出一个异常。异常只不过是PHP用一个特定的错误信息崩溃而已。当一个异常被抛出时,PHP就停止了。错误之后的任何一行代码都不会被执行。
作为一个负责任的开发者,你的工作是捕捉这个异常,并对它进行处理,以便程序能够继续运行。
注意:如果你没有捕捉到一个异常,PHP将停止运行你的PHP脚本,并显示一个非常难看的错误信息。那条错误信息甚至会显示出引发错误的脚本的代码。在这种情况下,这段代码包含了你的MySQL用户名和密码,所以避免错误信息被用户看到是非常重要的。
为了捕捉一个异常,你应该用一个try … catch 语句来包围可能抛出异常的代码。
try {
⋮ do something risky
}
catch (ExceptionType $e) {
⋮ handle the exception
}
你可以把try … catch 语句想成是if … else 语句,只不过第二个代码块是在第一个代码块运行失败时发生的。
困惑了吗?我知道我向你抛出了(不是双关语)很多新的概念,但如果我把它们放在一起并向你展示我们的东西,就会更有意义。
try {
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser',
’mypassword’);
$output = 'Database connection established.';
}
catch (PDOException $e) {
$output = 'Unable to connect to the database server.';
}
include __DIR__ . '/../templates/output.html.php';
正如你所看到的,这段代码是一个try … catch 语句。在顶部的try 块中,我们尝试使用new PDO 连接到数据库。如果成功了,我们将产生的PDO对象存储在$pdo ,这样我们就可以使用我们新的数据库连接。如果连接成功,$output 变量将被设置为一条信息,稍后将被显示。
重要的是,在try … catch 语句里面,任何抛出异常后的代码都不会被执行。在这种情况下,如果连接数据库抛出了一个异常(可能是密码错误,或者服务器没有响应),$output 变量将永远不会被设置为 "数据库连接已建立"。
如果我们的数据库连接尝试失败了,PHP将抛出一个PDOException ,这就是new PDO 抛出的异常类型。因此,我们的catch 块说,它将捕获一个PDOException(并将其存储在一个名为$e 的变量中)。在该块中,我们设置变量$output ,以包含一条关于出错的信息。
然而,这个错误信息并不特别有用。它只告诉我们PDO无法连接到数据库服务器。最好是有一些关于为什么会这样的信息--例如,因为用户名和密码是无效的。
$e 变量包含了关于发生的异常的细节,包括描述问题的错误信息。我们可以使用连接法将其添加到输出变量中。
try {
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser',
'mypassword');
$output = 'Database connection established.';
}
catch (PDOException $e) {
$output = 'Unable to connect to the database server: ' . $e->getMessage();
}
include __DIR__ . '/../templates/output.html.php';
注意:$e 这个变量不是一个字符串,而是一个对象。我们很快就会知道这意味着什么。不过现在,你需要知道的是,代码$e->getMessage() ,根据发生的特定异常得到错误信息。
与if … else 语句一样,try … catch 语句的两个分支中的一个保证会运行。要么try 块中的代码将成功执行,要么catch 块中的代码将运行。无论数据库连接是否成功,$output 变量中都会有一条信息--要么是错误信息,要么是说连接成功的信息。
最后,不管try 块是否成功,或者catch 块是否运行,模板output.html.php 。这是一个通用的模板,只是向页面显示一些文本。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Script Output</title>
</head>
<body>
<?php echo $output; ?>
</body>
</html>
完整的代码可以在例子中找到**。MySQL-Connect**。
当模板被包含时,它将显示错误信息或 "数据库连接建立 "信息。
我希望上述代码现在对你有了一些意义。如果你迷失了方向,可以随时回到本节的开头再读一遍,因为里面有一些棘手的概念。然而,一旦你牢牢掌握了这些代码,你可能会意识到,我仍然留下了一个未解释的谜团。PDO。究竟什么是new PDO ,当我说它返回一个 "PDO对象 "时,究竟什么是对象?
注意:所有下载的示例代码都包括一个叫做ijdb_sample 的模式和一个叫做ijdb_sample 的用户,这样你就可以运行它,不管你的模式和用户叫什么。一个包含数据库的文件被提供为database.sql ,你可以导入该文件。
如果你使用所提供的基于网络的样本代码查看器,idbj_sample 数据库将在你加载样本时被创建,但当你查看另一个样本时,对这个模式的任何改变都会丢失。(你可以把事情弄得一团糟,切换到另一个样本再切换回来就会重新设置,但如果你想保留你所做的任何改变,就在你创建的模式中进行。)
如果你想使用MySQL Workbench将样本数据加载到你的模式中,通过选择数据导入/恢复从project 目录中导入database.sql 。然后选择从自含文件导入,浏览到database.sql ,并在默认的目标模式中选择你的模式名称。如果你已经创建了任何同名的表,它们会被覆盖,所有记录都会丢失。
面向对象编程的速成课程
你可能已经注意到在上一节中 "对象 "这个词开始悄悄进入我的词汇表。PDO是PHP数据对象的扩展,new PDO ,返回一个PDO对象。在本节中,我想解释一下对象是怎么回事。
也许你在自己对PHP或一般编程的探索中遇到过**面向对象编程(OOP)**这个术语。OOP是一种高级的编程风格,特别适合于建立有很多部分的真正复杂的程序。今天大多数正在使用的编程语言都支持OOP。有些语言甚至要求你以OOP的方式工作。PHP在这方面比较随和,它让开发者决定是否用OOP风格来写他们的脚本。
到目前为止,我们已经用一种更简单的风格写了我们的PHP代码,叫做程序化编程,现在我们将继续这样做,以后会对对象进行更详细的研究。程序性风格很适合我们目前正在处理的相对简单的项目。然而,几乎所有你会遇到的复杂项目都会使用OOP,我将在本书后面更详细地介绍它。
也就是说,我们用来连接和使用MySQL数据库的PDO扩展是按照面向对象的编程风格设计的。这意味着,我们必须首先创建一个代表我们的数据库连接的PDO对象,然后使用该对象的特性与数据库一起工作,而不是简单地调用一个函数来连接到MySQL,然后再调用其他使用该连接的函数。
创建一个对象很像调用一个函数。事实上,你已经看到如何做了。
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser',
'mypassword');
new 关键字告诉PHP,你想创建一个新的对象。然后留下一个空格并指定一个类的名称,它告诉PHP你想创建什么类型的对象。一个类是一组指令,PHP将遵循它来创建一个对象。你可以把类看成是一个食谱,比如说蛋糕,而对象就是按照食谱制作的实际蛋糕。不同的类可以产生不同的对象,就像不同的菜谱可以产生不同的菜肴一样。
就像PHP有一堆可以调用的内置函数一样,PHP也有一个类库,可以从中创建对象。new PDO因此,告诉PHP创建一个新的PDO 对象--也就是一个内置的PDO 类的新对象。
在PHP中,对象是一个值,就像一个字符串、数字或数组。你可以把一个对象存储在一个变量中,或者把它作为一个参数传递给一个函数--所有你可以对其他PHP值做的事情。然而,对象有一些有用的附加功能。
首先,一个对象的行为很像一个数组,因为它可以作为其他值的容器。正如我们在第2章中所看到的,你可以通过指定数组的索引来访问数组中的一个值(例如,$birthdays['Kevin'] )。当涉及到对象时,概念是相似的,但名称和代码是不同的。我们不是访问存储在数组索引中的值,而是说我们在访问对象的一个属性。我们不使用方括号来指定我们要访问的属性的名称,而是使用箭头符号(->) - 例如,$myObject->someProperty 。
$myObject = new SomeClass(); // create an object
$myObject->someProperty = 123; // set a property's value
echo $myObject->someProperty; // get a property's value
数组通常用于存储类似值的列表(例如生日数组),而对象则用于存储相关值的列表(例如,数据库连接的属性)。不过,如果这就是对象的全部功能,那么它们就没有什么意义了:我们还不如用数组来存储这些值,对吗?当然,对象做的更多。
除了存储一系列的属性和它们的值之外,对象还可以包含一组旨在为我们带来更多有用功能的函数。一个存储在对象中的函数被称为方法(如果你问我,这是编程世界中比较混乱的名字之一)。一个方法只是一个类里面的函数。更令人困惑的是,当我们开始编写自己的类时,方法是用function 关键字来定义的。即使是有经验的开发者也经常错误地将函数和方法互换使用。
为了调用一个方法,我们再次使用箭头符号--$myObject->someMethod() 。
$myObject = new SomeClass(); // create an object
$myObject->someMethod(); // call a method
就像独立的函数一样,方法可以接受参数和返回值。
在这个阶段,这听起来可能有点复杂和无意义,但请相信我:把变量(属性)和函数(方法)的集合拉到称为对象的小包中,对于某些任务来说,代码会更加整洁和容易阅读--使用数据库只是其中之一。有一天,你甚至可能想要开发自定义类,用来创建你自己设计的对象。
然而现在,我们将坚持使用PHP中包含的类。让我们继续使用我们已经创建的PDO 对象,看看我们可以通过调用它的一个方法来做什么。
配置连接
到目前为止,我已经向你展示了如何创建一个PDO 对象来与你的MySQL数据库建立连接,以及如何在出错时显示一个有意义的错误信息。
<?php
try {
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword');
$output = 'Database connection established.';
} catch (PDOException $e) {
$output = 'Unable to connect to the database server: ' . $e->getMessage();
}
include __DIR__ . '/../templates/output.html.php';
不过,假设连接成功,你需要在使用前对其进行配置。你可以通过调用你的新PDO 对象的一些方法来配置你的连接。
在向数据库发送查询之前,我们需要配置数据库连接的字符编码。正如我在第2章中简单提到的,在网站中应该使用UTF-8编码的文本,以使用户在网站上填写表格时能最大限度地利用他们所掌握的字符范围。默认情况下,当PHP连接到MySQL时,它使用较简单的ISO-8859-1(或Latin-1)编码而不是UTF-8。如果我们让它保持原样,我们就不容易插入中文、阿拉伯文或大多数非英文字符。
即使你100%确定你的网站只会被讲英语的人使用,不设置字符集还会引起其他问题。如果你的网页没有设置为UTF-8,当人们在文本框中写入某些字符,如大括号” ,你会遇到问题,因为它们在数据库中会显示为不同的字符。
因此,我们现在需要将我们新的PDO 对象设置为使用UTF-8编码。
我们可以通过在连接字符串中添加;charset=utf8mb4 来指示PHP在查询数据库时使用UTF-8。这样做没有什么坏处,只要你的PHP脚本也是以UTF-8 (这是最近的PHP版本中的默认值)发送给浏览器的。
$pdo = new PDO('mysql:host=mysql;dbname=ijdb;charset=utf8mb4', 'ijdbuser',
'mypassword');
注意:如果你去搜索,你会发现有不同的方法来设置字符集,而本书的早期版本指示你使用这段代码。
$pdo->exec('SET NAMES "utf8"');
这是因为,在PHP 5.3.6之前,字符集选项不能被PHP正确应用。由于这在你实际要使用的任何PHP版本中都是固定的,所以将字符集作为连接字符串的一部分来设置是首选方案。
因此,我们用来连接到MySQL并配置该连接的完整代码如下所示。
<?php
try {
$pdo = new PDO('mysql:host=mysql;dbname=ijdb;charset=utf8mb4', 'ijdbuser', 'mypassword');
$output = 'Database connection established.';
} catch (PDOException $e) {
$output = 'Unable to connect to the database server: ' . $e->getMessage();
}
include __DIR__ . '/../templates/output.html.php';
在你的浏览器中启动这个例子。(如果你把你的数据库代码放在public 目录内的index.php ,把output.html.php 文件放在templates 目录内,那么这个页面的URL将是https://v.je/ 。)
如果你的服务器已经启动并运行,而且一切工作正常,你应该看到一条表示成功的信息。
如果 PHP 无法连接到你的 MySQL 服务器,或者你提供的用户名和密码不正确,你会看到一个类似于下图的屏幕。为了确保你的错误处理代码工作正常,你可能想故意把密码拼错来测试一下。
感谢我们的catch 块,来自数据库的错误信息已经包含在页面上。
catch (PDOException $e) {
$output = 'Unable to connect to the database server: ' . $e->getMessage();
}
方法getMessage() ,返回描述所发生的异常的信息。还有一些其他的方法--包括getFile() 和getLine() --用于返回抛出异常的文件名和行号。你可以像这样生成一个非常详细的错误信息。
catch (PDOException $e) {
$output = 'Unable to connect to the database server: ' . $e->getMessage() . ' in ' .
$e->getFile() . ':' . $e->getLine();
}
如果你有一个有几十个include文件的大型网站,这就非常有用。这个错误信息会告诉你到底该看哪个文件,错误发生在哪一行。
如果你很好奇,试着在你的数据库连接代码中插入一些其他的错误(例如,一个拼错的数据库名称),观察所产生的详细错误信息。当你完成后,你的数据库连接工作正常时,再回到简单的错误信息。这样,如果你的数据库服务器出现了真正的问题,你的访问者就不会被技术上的胡言乱语所困扰了。
随着连接的建立和数据库的选择,你已经准备好开始使用存储在数据库中的数据。
你可能想知道,在脚本执行完毕后,与MySQL服务器的连接会发生什么。如果你真的想,你可以通过丢弃代表连接的PDO 对象来强迫 PHP 与服务器断开连接。通过将包含该对象的变量设置为null 来做到这一点。
$pdo = null; // disconnect from the database server
也就是说,PHP在运行完脚本后会自动关闭任何打开的数据库连接,所以通常可以让PHP在你之后进行清理。
继续阅读《在网络上显示来自MySQL的数据: SitePoint的介绍》。