PDO是什么,PHP PDO操作MySQL详解(附带实例,新手必看)
随着 PHP 应用的快速增长和 PHP 开发跨平台应用的出现,使用不同的数据库是十分常见的。PHP 需要支持从 MySQL、MS SQL 到 Oracle 数据库的多种数据库。
如果只是通过单一的接口针对单一的数据库编写程序,比如用 MySQL 函数处理 MySQL 数据库,用其他函数处理 Oracle 数据库,会在很大程度上增添PHP程序在数据库方面的灵活性并提高编程的复杂性和工作量。
如果通过 PHP 开发一个跨数据库平台的应用,比如对于一类数据需要到两个不同的数据库中提取,在使用传统方法的情况下,只有两个不同的数据库连接程序,并且要对两个数据库连接的工作过程进行协调。为了解决这个问题,程序员开发出了“数据库抽象层”。通过这个抽象层,把数据处理业务逻辑和数据库连接区分开来。也就是说,无论 PHP 连接的是什么数据库,都不影响 PHP 业务逻辑程序。这样对于一个应用来说,可以采用若干不同的数据库支持方案。
PDO 就是 PHP 中最为主流的实现“数据库抽象层”的数据库抽象类。
PDO 类是 PHP 5 中最为突出的功能之一。PHP 5 版本以前,PHP 都只能通过针对 MySQL 的类库、针对 PostgreSQL 的类库、针对 MS SQL 的类库等实现针对性的数据库连接。
PDO 通过数据库抽象层实现了以下特性:
1) 首先启用 extension=php_pdo.dll 类库,这个类库是 PDO 类库本身。
2) 然后设置不同的数据库驱动类库选项:
除了这些外,还有支持 PgSQL 和 SQLite 等的类库。本机环境下启用的类库为 extension=pdo_mysql。
实现这个操作是通过 PDO 类库内部的构造函数来完成的。PDO 构造函数的结构是:
DSN 是一个字符串,字符串由“数据库服务器类型”“数据库服务器地址”和“数据库名称”组合得到。它们组合的格式为:
例如使用 MySQL 作为数据库生成一个数据库连接,代码如下:
另外,用户也可以使用简洁的方式连接数据库,代码如下:
以下案例通过对数据库请求的错误处理来说明此结构。具体步骤如下:
1) 在 MySQL 数据库中建立 pdodatabase 数据库,并且在 SQL 编辑框中执行以下 SQL 语句:
插入数据,SQL 语句如下:
2) 在网站下建立 pdodemo.php 文件,输入如下代码:
3) 运行 pdodemo.php 网页,结果如下图所示:

图 1 程序运行结果
在创建 PDO 实例的过程中,由于密码是错误的,因此 PDO 通过 try catch 结构抛出错误信息。
在 pdodemo.php 文件中,catch(PDOException $exception){} 使用了 PDOException 类。前面提到的 PDO::ATTR_ERRMODE 选项的 PDO:: ERRMODE_EXCEPTION 例外模式使用 PDOException 类来抛出错误信息,如果有错误产生,就会即时终止程序执行,并输出错误信息。这个类在此程序中的实例是 $exception。
以上是建立 PDO 数据库连接的发生错误时获得错误信息的方法。那么如果 SQL 请求在执行的过程中出错,其错误信息应当如何获取呢?
下面就介绍此方法。具体步骤如下:
1) 在网站下建立 pdodemo2.php 文件,输入代码如下:
2) 运行 pdodemo2.php 网页,结果如下图所示:
$sqlquery 定义了 SQL 请求语句。$dbconnect->exec($sqlquery); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句。
由于 $sqlquery 定义的 SQL 请求语句中 'users' 不正确(应为 'user'),因此 $dbconnect->errorCode(); 语句直接输出 SQL 请求的错误代码 42S02,表示目标数据表不存在。
$dbconnect-> errorInfo(); 语句则获得错误的所有信息,包括错误代码。但是由于类方法 error::Info() 返回的是一个数字索引数组,因此使用 print_r() 显示。此数组拥有 3 个数组元素。第一个元素为遵循 SQL 标准的状态码。第二个元素为遵循数据库标准的错误代码。第三个元素为具体的错误信息。
实例 $dbconnect 其实是使用 PDO 类的类方法 PDOStatment::errorCode() 来获得 SQL 错误代码的。错误信息则是通过 PDO 类的类方法 PDOStatment::errorInfo() 来获得的。
1) 在网站下建立 pdoselect.php 文件,输入如下代码:
2) 运行 pdoselect.php 网页,结果如下图所示:
其中,$sqlquery 定义了 SQL 请求语句。$dbconnect->query($sqlquery); 语句通过实例 $dbconnect 的实例方法 query() 执行 $sqlquery 的 SQL 请求语句。在执行 SQL 语句的 select 操作时,一定要使用 query() 方法,而不能使用执行其他操作时使用的 exec() 方法。
foreach ($result as $row) 语句以默认的方法获取 $result 这一返回数据对象的所有数据,并且以关联数组的形式表现出来。
通过 fetch() 方法读取请求所返回的数据对象的一条记录。fetch 方法是 PDOStatement::fetch() 类方法在实例化之后的运用。可以选择 fetch_style 的选项作为其参数。例如:
通过 fetchAll() 方法读取请求所返回的数据对象的所有记录。
下面通过例子来讲解 fetch() 方法的使用技巧。
1) 在网站下建立 pdofetch.php 文件,输入如下代码:
2) 运行 pdofetch.php,结果如下图所示。
其中,$sqlquery 定义了 SQL 请求语句。$dbconnect->query($sqlquery); 语句通过实例 $dbconnect 的实例方法 query() 执行 $sqlquery 的 SQL 请求语句。返回对象为 $result。
$row = $result->fetch(PDO::FETCH_ASSOC) 语句直接以关联数组的方式取得 $result 的一条记录,并且赋值给 $row。使用 while 循环按照输出格式打印。
以下实例介绍 fetchAll() 方法的使用技巧。
1) 在网站下建立 pdofetchall.php 文件,输入如下代码:
2) 运行 pdofetchall.php 网页,结果如下图所示:
其中,$sqlquery 定义了 SQL 请求语句。$dbconnect->query($sqlquery); 语句通过实例 $dbconnect 的实例方法 query() 执行 $sqlquery 的 SQL 请求语句,返回对象为 $result。rowCount() 方法用于返回数据对象的记录条数。
$rowall = $result->fetchAll(); 语句取得 $result 的所有记录,并且赋值给 $rowall。然后使用 foreach 循环遍历数组元素。
由于 fetchAll() 方法用于读取 $result 对象为数字索引数组和关联数组两种类型,因此在遍历的时候可以使用两种方式指定数组元素。
1) 在网站下建立 pdoinsertupdate.php 文件,输入如下代码:
2) 运行 pdoinsertupdate.php,结果如下图所示:
其中,$sqlquery 定义了 insert 的 SQL 请求语句。$dbconnect->exec($sqlquery); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句,若正确执行,则提示新数据插入成功。
$sqlquery2 定义了 update 的 SQL 请求语句。$dbconnect->exec($sqlquery2); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句,若正确执行,则提示数据更新成功。
1) 在网站下建立 pdodelete.php 文件,输入如下代码:
2) 运行 pdoidelete.php,结果如下图所示:
其中,$sqlquery 定义了 delete 的 SQL 请求语句。$dbconnect->exec($sqlquery); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句,若正确执行,则提示数据被删除了。
如果只是通过单一的接口针对单一的数据库编写程序,比如用 MySQL 函数处理 MySQL 数据库,用其他函数处理 Oracle 数据库,会在很大程度上增添PHP程序在数据库方面的灵活性并提高编程的复杂性和工作量。
如果通过 PHP 开发一个跨数据库平台的应用,比如对于一类数据需要到两个不同的数据库中提取,在使用传统方法的情况下,只有两个不同的数据库连接程序,并且要对两个数据库连接的工作过程进行协调。为了解决这个问题,程序员开发出了“数据库抽象层”。通过这个抽象层,把数据处理业务逻辑和数据库连接区分开来。也就是说,无论 PHP 连接的是什么数据库,都不影响 PHP 业务逻辑程序。这样对于一个应用来说,可以采用若干不同的数据库支持方案。
PDO 就是 PHP 中最为主流的实现“数据库抽象层”的数据库抽象类。
PDO 类是 PHP 5 中最为突出的功能之一。PHP 5 版本以前,PHP 都只能通过针对 MySQL 的类库、针对 PostgreSQL 的类库、针对 MS SQL 的类库等实现针对性的数据库连接。
PDO 通过数据库抽象层实现了以下特性:
- 灵活性:可以在 PHP 运行期间直接加载新的数据库,而不需要在使用新的数据库时重新设置和编译;
- 面向对象:这个特性完全配合了 PHP 5,通过对象来控制数据库的使用;
- 速度极快:由于 PDO 使用 C语言编写并且编译进 PHP,因此比那些用 PHP 编写的抽象类要快得多。
PHP PDO的安装
由于 PDO 类库是 PHP 自带的类库,因此要使用 PDO 类库,只需要在 php.ini 中把关于 PDO 类库的语句前面的注释符号去掉即可。1) 首先启用 extension=php_pdo.dll 类库,这个类库是 PDO 类库本身。
2) 然后设置不同的数据库驱动类库选项:
- extension=php_pdo_mysql.dll 适用于 MySQL 数据库的连接;
- 如果使用 MS SQL,可以启用 extension=php_pdo_mssql.dll 类库;
- 如果使用Oracle数据库,可以启用 extension=php_pdo_oci.dll 类库。
除了这些外,还有支持 PgSQL 和 SQLite 等的类库。本机环境下启用的类库为 extension=pdo_mysql。
使用PDO操作MySQL
在本环境下使用的数据库是 MySQL,所以在使用 PDO 操作数据库之前,首先需要连接到 MySQL 服务器和特定的 MySQL 数据库。实现这个操作是通过 PDO 类库内部的构造函数来完成的。PDO 构造函数的结构是:
PDO::__constuct(DSN, username, password, driver_options)其中,DSN 是一个“数据源名称”,username 是接入数据源的用户名,password 是用户密码,driver_options 是特定连接要求的其他参数。
DSN 是一个字符串,字符串由“数据库服务器类型”“数据库服务器地址”和“数据库名称”组合得到。它们组合的格式为:
'数据库服务器类型:host=数据库服务器地址;dbname=数据库名称'driver_options 是一个数组,它有很多选项,如下表所示:
选项 | 描述 |
---|---|
PDO::ATTR_AUTOCOMMIT | 定义 PDO 在执行时是否注释每条请求。 |
PDO::ATTR_CASE |
控制从数据库中取得的数据的字母大小写。具体来说就是:
|
PDO::ATTR_EMULATE_PREPARES | 利用 MySQL 的请求缓存功能。 |
PDO::ATTR_ERRMODE |
定义 PDO 的错误报告模型。具体的 3 种模式分别为:
|
PDO::ATTR_ORACLE_NULLS | 在使用 Oracle 数据库时,会把空字符串转换为 NULL 值。一般情况下,此选项为默认关闭。 |
PDO::ATTR_PERSISTENT | 确定此数据库连接是否可持续。但是其默认值为 false,不启用。 |
PDO::ATTR_PREFETCH | 确定是否要使用数据库 prefetch 功能。此功能是在用户取得一条记录操作之前就取得多条记录,以准备给下一次请求数据操作提供数据,并且减少了执行数据库请求的次数,提高了效率。 |
PDO::ATTR_TIMEOUT | 设置超时时间为多少秒,但是 MySQL 不支持此功能。 |
PDO::DEFAULT_FETCH_MODE | 设定默认的 fetch 模型,包括以联合数据的形式取得数据,或者以数字索引数组的形式取得数据,或者以对象的形式取得数据。 |
1、连接MySQL数据库的方法
当建立一个连接对象的时候,只需要使用 new 关键字生成一个 PDO 的数据库连接实例。例如使用 MySQL 作为数据库生成一个数据库连接,代码如下:
<?php $dbms='mysql'; //数据库类型 $host='localhost'; //数据库主机名 $dbName=' pdodatabase '; //使用的数据库 $user='root'; //数据库连接用户名 $pass=' '; //对应的密码 $dsn="$dbms:host=$host;dbname=$dbName"; $dbh = new PDO($dsn, $user, $pass); //初始化一个PDO对象 ?>
另外,用户也可以使用简洁的方式连接数据库,代码如下:
$dbconnect = new PDO(‘mysql:host=localhost;dbname=pdodatabase’,’root’,’753951’)
2、使用PDO时的try catch错误处理结构
使用 PDO 的时候,经常伴随着 PHP 中的 try catch 处理异常机制进行编码,如下所示:<?php try { $dbconnect = new PDO($dsn, $user, $pass); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } ?>使用这样的结构,PDO 可以配合其他的对象属性获得更多的信息。
以下案例通过对数据库请求的错误处理来说明此结构。具体步骤如下:
1) 在 MySQL 数据库中建立 pdodatabase 数据库,并且在 SQL 编辑框中执行以下 SQL 语句:
CREATE TABLE IF NOT EXISTS `user` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(30) DEFAULT NULL, `age` int(10) NOT NULL, `gender` varchar(10) NOT NULL, `info` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
插入数据,SQL 语句如下:
INSERT INTO `user` (`id`, `name`, `age`, `gender`, `info`) VALUES (1, 'wangxiaoming', 32, 'male', 'He is a man'), (2, 'lilili', 23, 'female', 'She is a woman'), (3, 'fangfanfang', 18, 'female', 'She is a 18 years old lady.'), (7, 'liuxiaoyong', 17, 'male', 'He is a young boy.');至此,数据库 pdodatabase 和数据库表格 user 以及其中的数据都已创建。
2) 在网站下建立 pdodemo.php 文件,输入如下代码:
<?php $dbms='mysql'; //数据库类型 $host='localhost'; //数据库主机名 $dbName=' pdodatabase '; //使用的数据库 $user='root'; //数据库连接用户名 $pass='123456'; //对应的密码 $dsn="$dbms:host=$host;dbname=$dbName"; try { $dbconnect = new PDO($dsn, $user, $pass); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } ?>
3) 运行 pdodemo.php 网页,结果如下图所示:

图 1 程序运行结果
在创建 PDO 实例的过程中,由于密码是错误的,因此 PDO 通过 try catch 结构抛出错误信息。
在 pdodemo.php 文件中,catch(PDOException $exception){} 使用了 PDOException 类。前面提到的 PDO::ATTR_ERRMODE 选项的 PDO:: ERRMODE_EXCEPTION 例外模式使用 PDOException 类来抛出错误信息,如果有错误产生,就会即时终止程序执行,并输出错误信息。这个类在此程序中的实例是 $exception。
以上是建立 PDO 数据库连接的发生错误时获得错误信息的方法。那么如果 SQL 请求在执行的过程中出错,其错误信息应当如何获取呢?
下面就介绍此方法。具体步骤如下:
1) 在网站下建立 pdodemo2.php 文件,输入代码如下:
<?php try { $dbconnect = new PDO('mysql:host=localhost;dbname=pdodatabase','root','753951'); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } $sqlquery = "SELECT * FROM users"; $dbconnect->exec($sqlquery); echo $dbconnect->errorCode()."<br/>"; print_r($dbconnect->errorInfo()); ?>
2) 运行 pdodemo2.php 网页,结果如下图所示:

$sqlquery 定义了 SQL 请求语句。$dbconnect->exec($sqlquery); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句。
由于 $sqlquery 定义的 SQL 请求语句中 'users' 不正确(应为 'user'),因此 $dbconnect->errorCode(); 语句直接输出 SQL 请求的错误代码 42S02,表示目标数据表不存在。
$dbconnect-> errorInfo(); 语句则获得错误的所有信息,包括错误代码。但是由于类方法 error::Info() 返回的是一个数字索引数组,因此使用 print_r() 显示。此数组拥有 3 个数组元素。第一个元素为遵循 SQL 标准的状态码。第二个元素为遵循数据库标准的错误代码。第三个元素为具体的错误信息。
实例 $dbconnect 其实是使用 PDO 类的类方法 PDOStatment::errorCode() 来获得 SQL 错误代码的。错误信息则是通过 PDO 类的类方法 PDOStatment::errorInfo() 来获得的。
3、使用PDO执行SQL的选择语句
PDO 执行 SQL 的选择语句会返回结果对象,可以通过 foreach 来遍历对象内容。下面介绍此内容,具体步骤如下:1) 在网站下建立 pdoselect.php 文件,输入如下代码:
<?php try { $dbconnect = new PDO('mysql:host=localhost;dbname=pdodatabase','root','753951'); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } $sqlquery = "SELECT * FROM user"; $result = $dbconnect->query($sqlquery); foreach ($result as $row){ $name = $row['name']; $gender = $row['gender']; $age = $row['age']; echo "user $name , is $gender ,and is $age years old. <br/>"; } ?>
2) 运行 pdoselect.php 网页,结果如下图所示:

其中,$sqlquery 定义了 SQL 请求语句。$dbconnect->query($sqlquery); 语句通过实例 $dbconnect 的实例方法 query() 执行 $sqlquery 的 SQL 请求语句。在执行 SQL 语句的 select 操作时,一定要使用 query() 方法,而不能使用执行其他操作时使用的 exec() 方法。
foreach ($result as $row) 语句以默认的方法获取 $result 这一返回数据对象的所有数据,并且以关联数组的形式表现出来。
4、使用PDO获取返回数据的类方法
当使用 select 语句向数据库请求数据以后,query() 方法会返回一个包含所有请求数据的对象。如何对这个对象的数据进行读取操作,我们将通过下面的类方法来讲解。通过 fetch() 方法读取请求所返回的数据对象的一条记录。fetch 方法是 PDOStatement::fetch() 类方法在实例化之后的运用。可以选择 fetch_style 的选项作为其参数。例如:
- PDO::FETCH_ASSOC 选项是把返回的数据读取为关联数组;
- PDO::FETCH_NUM 选项是把返回的数据读取为数字索引数组;
- PDO_FETCH_BOTH 选项是把返回的数据读取为数组,包括数字索引数组和关联数组;
- PDO::FETCH_OBJ 选项是把返回的数据读取为一个对象,不同字段的数据作为其对象属性。
通过 fetchAll() 方法读取请求所返回的数据对象的所有记录。
下面通过例子来讲解 fetch() 方法的使用技巧。
1) 在网站下建立 pdofetch.php 文件,输入如下代码:
<?php try { $dbconnect = new PDO('mysql:host=localhost;dbname=pdodatabase','root','753951'); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } $sqlquery = "SELECT * FROM user"; $result = $dbconnect->query($sqlquery); $rownum = $result->rowCount(); echo "总共有".$rownum." 个用户:<br/>"; while ($row = $result->fetch(PDO::FETCH_ASSOC)){ $name = $row['name']; $gender = $row['gender']; $age = $row['age']; echo "user $name , is $gender ,and is $age years old. <br/>"; } ?>
2) 运行 pdofetch.php,结果如下图所示。

其中,$sqlquery 定义了 SQL 请求语句。$dbconnect->query($sqlquery); 语句通过实例 $dbconnect 的实例方法 query() 执行 $sqlquery 的 SQL 请求语句。返回对象为 $result。
$row = $result->fetch(PDO::FETCH_ASSOC) 语句直接以关联数组的方式取得 $result 的一条记录,并且赋值给 $row。使用 while 循环按照输出格式打印。
以下实例介绍 fetchAll() 方法的使用技巧。
1) 在网站下建立 pdofetchall.php 文件,输入如下代码:
<?php try { $dbconnect = new PDO('mysql:host=localhost;dbname=pdodatabase','root','753951'); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } $sqlquery = "SELECT * FROM user"; $result = $dbconnect->query($sqlquery); $rownum = $result->rowCount(); echo "总共有".$rownum." 个用户:<br/>"; $rowall = $result->fetchAll(); foreach ($rowall as $row){ $id = $row[0]; $name = $row[1]; $gender = $row[3]; $age = $row[2]; $info = $row['info']; echo "ID: $id . User $name , is $gender ,and is $age years old. and info: $info<br/>"; } ?>
2) 运行 pdofetchall.php 网页,结果如下图所示:

其中,$sqlquery 定义了 SQL 请求语句。$dbconnect->query($sqlquery); 语句通过实例 $dbconnect 的实例方法 query() 执行 $sqlquery 的 SQL 请求语句,返回对象为 $result。rowCount() 方法用于返回数据对象的记录条数。
$rowall = $result->fetchAll(); 语句取得 $result 的所有记录,并且赋值给 $rowall。然后使用 foreach 循环遍历数组元素。
由于 fetchAll() 方法用于读取 $result 对象为数字索引数组和关联数组两种类型,因此在遍历的时候可以使用两种方式指定数组元素。
5、使用PDO执行SQL的添加、修改语句
使用PDO执行添加和修改的SQL命令不同于Select操作。以下实例介绍此方面的内容。1) 在网站下建立 pdoinsertupdate.php 文件,输入如下代码:
<?php try { $dbconnect = new PDO('mysql:host=localhost;dbname=pdodatabase','root','753951'); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } $sqlquery = "INSERT INTO user (id,name,age,gender,info )VALUES (NULL,'zhangdaguang', '39', 'male', 'he is a middle-age male.')"; if($dbconnect->exec($sqlquery)){ echo "新数据插入成功!<br />"; } $sqlquery2 = "UPDATE user SET age='45' WHERE name='zhangdaguang'"; if($dbconnect->exec($sqlquery2)){ echo "数据更新成功"; } ?>
2) 运行 pdoinsertupdate.php,结果如下图所示:

其中,$sqlquery 定义了 insert 的 SQL 请求语句。$dbconnect->exec($sqlquery); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句,若正确执行,则提示新数据插入成功。
$sqlquery2 定义了 update 的 SQL 请求语句。$dbconnect->exec($sqlquery2); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句,若正确执行,则提示数据更新成功。
6、使用PDO执行SQL的删除语句
删除一个记录也使用 exec() 类方法。下面通过实例来讲解这方面的内容。1) 在网站下建立 pdodelete.php 文件,输入如下代码:
<?php try { $dbconnect = new PDO('mysql:host=localhost;dbname=pdodatabase','root','753951'); } catch (PDOException $exception) { echo "Connection error message: " . $exception->getMessage(); } $sqlquery = "DELETE FROM user WHERE name = 'zhangdaguang'"; if($dbconnect->exec($sqlquery)){ echo "一条数据被删除了!"; } ?>
2) 运行 pdoidelete.php,结果如下图所示:

其中,$sqlquery 定义了 delete 的 SQL 请求语句。$dbconnect->exec($sqlquery); 语句通过实例 $dbconnect 的实例方法 exec() 执行 $sqlquery 的 SQL 请求语句,若正确执行,则提示数据被删除了。