原文: https://zetcode.com/php/pdo/

在本教程中,我们展示了如何在 PHP PDO 中对数据库进行编程。

PHP PDO

PHP 数据对象(PDO)定义了用于访问 PHP 中数据库的轻量级接口。 它提供了一个数据访问抽象层,用于在 PHP 中使用数据库。 它定义了用于各种数据库系统的一致 API。

PHP PDO 类

PDO表示 PHP 与数据库服务器之间的连接。 PDOStatement代表准备好的语句,在执行该语句后,代表关联的结果集。 PDOException表示 PDO 引发的错误。

MySQL 数据库

在本教程中,我们将使用 MySQL 数据库。

countries_mysql.sql

  1. DROP TABLE IF EXISTS countries;
  2. CREATE TABLE countries(id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  3. name VARCHAR(255), population INT);
  4. INSERT INTO countries(name, population) VALUES('China', 1382050000);
  5. INSERT INTO countries(name, population) VALUES('India', 1313210000);
  6. INSERT INTO countries(name, population) VALUES('USA', 324666000);
  7. INSERT INTO countries(name, population) VALUES('Indonesia', 260581000);
  8. INSERT INTO countries(name, population) VALUES('Brazil', 207221000);
  9. INSERT INTO countries(name, population) VALUES('Pakistan', 196626000);
  10. INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
  11. INSERT INTO countries(name, population) VALUES('Bangladesh', 162099000);
  12. INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
  13. INSERT INTO countries(name, population) VALUES('Russia', 146838000);
  14. INSERT INTO countries(name, population) VALUES('Japan', 126830000);

这些 SQL 命令创建一个countries表。

PHP PDO 查询

PDO query()在单个函数调用中执行一条 SQL 语句,返回该语句返回的结果集(如果有)。

version.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $stm = $pdo->query("SELECT VERSION()");
  7. $version = $stm->fetch();
  8. echo $version[0] . PHP_EOL;

该示例返回 MySQL 的版本。

  1. $dsn = "mysql:host=localhost;dbname=mydb";
  2. $user = "user12";
  3. $passwd = "12user";

这些变量用于创建到数据库的连接字符串。 dsn是数据源名称,其中包含连接到数据库所需的信息。

  1. $pdo = new PDO($dsn, $user, $passwd);

创建一个新的PDO对象。 我们向构造器传递数据源名称以及用户名和密码。 PDO类表示 PHP 与数据库服务器之间的连接。

  1. $stm = $pdo->query("SELECT VERSION()");

query()方法在单个函数调用中执行一条 SQL 语句。 它返回结果集。

  1. $version = $stm->fetch();

PDO 语句的fetch()方法从结果集中获取下一行。 在我们的例子中,它是 MySQL 的一个版本。

  1. echo $version[0] . PHP_EOL;

$version是一个数组; 我们得到它的第一个值。

  1. $ php version.php
  2. 5.7.22-0ubuntu0.16.04.1

这是输出。

PHP PDO 执行

PDO exec()执行一条 SQL 语句并返回受影响的行数。

affected_rows.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $id = 12;
  7. $nrows = $pdo->exec("DELETE FROM countries WHERE id IN (1, 2, 3)");
  8. echo "The statement affected $nrows rows\n";

该代码示例将删除三行。 它打印受影响的行数。

  1. $nrows = $pdo->exec("DELETE FROM countries WHERE id IN (1, 2, 3)");

在此 SQL 语句中,我们删除 ID 为 1、2 和 3 的行。已删除的行数存储在$nrows变量中。

  1. echo "The statement deleted $nrows rows\n";

我们打印已删除的行数。

PHP PDO 提取样式

提取样式参数控制如何将下一行返回给调用方。 例如,PDO::FETCH_ASSOC返回按列名索引的数组,PDO::FETCH_NUM返回按列号索引的数组,PDO::FETCH_BOTH返回按列名和索引列号索引的数组。 默认的获取样式为PDO::FETCH_BOTH

fetch_style_num.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $stm = $pdo->query("SELECT * FROM countries");
  7. $rows = $stm->fetchAll(PDO::FETCH_NUM);
  8. foreach($rows as $row) {
  9. printf("$row[0] $row[1] $row[2]\n");
  10. }

在此代码示例中,我们在索引数组中获取数据。

  1. $stm = $pdo->query("SELECT * FROM countries");

我们从countries表中选择所有数据。

  1. $rows = $stm->fetchAll(PDO::FETCH_NUM);

我们将PDO:FETCH_NUM样式传递给fetchAll()方法。

  1. foreach($rows as $row) {
  2. printf("$row[0] $row[1] $row[2]\n");
  3. }

我们遍历$rows数组并打印字段。 通过数组索引访问这些字段。

fetch_style_assoc.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $stm = $pdo->query("SELECT * FROM countries");
  7. $rows = $stm->fetchAll(PDO::FETCH_ASSOC);
  8. foreach($rows as $row) {
  9. printf("{$row['id']} {$row['name']} {$row['population']}\n");
  10. }

在此示例中,我们以关联数组的形式获取数据。

  1. $rows = $stm->fetchAll(PDO::FETCH_ASSOC);

fetchAll()方法中,我们使用PDO::FETCH_ASSOC样式。

PHP PDO 参数绑定

SQL 语句通常是动态构建的。 用户提供一些输入,并且此输入已内置到语句中。 每当我们处理来自用户的输入时,我们都必须谨慎。 它具有一些严重的安全隐患。 动态构建 SQL 语句的推荐方法是使用参数绑定。

PDO 包含bindParam()bindValue()方法来创建参数化查询。

PDO 允许将数据绑定到问号或命名的占位符。

parameterized_query.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "root";
  4. $passwd = "andrea";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $id = 12;
  7. $stm = $pdo->prepare("SELECT * FROM countries WHERE id = ?");
  8. $stm->bindValue(1, $id);
  9. $stm->execute();
  10. $row = $stm->fetch(PDO::FETCH_ASSOC);
  11. echo "Id: " . $row['id'] . PHP_EOL;
  12. echo "Name: " . $row['name'] . PHP_EOL;
  13. echo "Population: " . $row['population'] . PHP_EOL;

在示例中,我们使用bindValue()创建参数化查询。 我们使用问号占位符。

  1. $id = 12;

说此输入来自用户。

  1. $stm = $pdo->prepare("SELECT * FROM countries WHERE id = ?");
  2. $stm->bindValue(1, $id);
  3. $stm->execute();

select语句从表中获取特定行。 我们将带有bindValue()的值绑定到问号占位符。

在第二种情况下,我们使用bindParam()

parameterized_query2.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $id = 12;
  7. $stm = $pdo->prepare("SELECT * FROM countries WHERE id = :id");
  8. $stm->bindParam(":id", $id, PDO::PARAM_INT);
  9. $stm->execute();
  10. $row = $stm->fetch(PDO::FETCH_ASSOC);
  11. echo "Id: " . $row['id'] . PHP_EOL;
  12. echo "Name: " . $row['name'] . PHP_EOL;
  13. echo "Population: " . $row['population'] . PHP_EOL;

该示例选择并打印特定的行。

  1. $stm = $pdo->prepare("SELECT * FROM countries WHERE id = :id");
  2. $stm->bindParam(":id", $id, PDO::PARAM_INT);
  3. $stm->execute();

这次我们使用命名占位符(:id)和bindParam()

PHP PDO 最后插入的行 ID

PDO lastInsertId()方法返回最后插入的行 ID。

create_table.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $sql = "CREATE TABLE words(id INT PRIMARY KEY AUTO_INCREMENT,
  7. word VARCHAR(255))";
  8. $ret = $pdo->exec($sql);
  9. $pdo->exec("INSERT INTO words(word) VALUES ('pen')");
  10. $pdo->exec("INSERT INTO words(word) VALUES ('bum')");
  11. $pdo->exec("INSERT INTO words(word) VALUES ('hum')");
  12. $pdo->exec("INSERT INTO words(word) VALUES ('den')");
  13. $rowid = $pdo->lastInsertId();
  14. echo "The last inserted row id is: $rowid\n";

在示例中,我们创建一个新表。 创建表后,我们用lastInsertId()找出最后插入的 ID。

  1. $ php create_table.php
  2. The last inserted row id is: 4

This is the output.

  1. mysql> select * from words;
  2. +----+------+
  3. | id | word |
  4. +----+------+
  5. | 1 | pen |
  6. | 2 | bum |
  7. | 3 | hum |
  8. | 4 | den |
  9. +----+------+
  10. 4 rows in set (0.01 sec)

我们验证数据。

PHP PDO 事务

事务是针对一个或多个数据库中数据的数据库操作的基本单位。 事务中所有 SQL 语句的影响可以全部提交给数据库,也可以全部回滚。

PDO beginTransaction()启动新事务。 PDO commit()提交事务。 PDO rollback()将回滚事务。

transaction.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. try {
  7. $pdo->beginTransaction();
  8. $stm = $pdo->exec("INSERT INTO countries(name, population) VALUES ('Iraq', 38274000)");
  9. $stm = $pdo->exec("INSERT INTO countries(name, population) VALUES ('Uganda', 37673800)");
  10. $pdo->commit();
  11. } catch(Exception $e) {
  12. $pdo->rollback();
  13. throw $e;
  14. }

在示例中,我们将两个新的国家/地区添加到数据库表中。 将insert语句放置在事务中:要么执行两个插入,要么都不执行。

  1. } catch(Exception $e) {
  2. $pdo->rollback();
  3. throw $e;
  4. }

如果发生异常,我们回滚事务:没有数据写入数据库。 我们抛出异常,以便异常处理继续按常规方式进行。

PHP PDO 获取元数据

元数据是有关数据库中数据的信息。 元数据包含有关我们存储数据的表和列的信息。 SQL 语句影响的行数是元数据。 结果集中返回的行数和列数也是元数据。

column_count.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $stm = $pdo->query("SELECT name, population FROM countries WHERE id=1");
  7. $ncols = $stm->columnCount();
  8. echo "The result set contains $ncols columns\n";

在示例中,我们使用columnCount()方法打印结果集中的列数。

getAttribute()方法检索数据库连接属性。

connection_attributes.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
  7. $server_version = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
  8. $autocommit_mode = $pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);
  9. echo "Driver: $driver\n";
  10. echo "Server version: $server_version\n";
  11. echo "Autocommit mode: $autocommit_mode\n";

在示例中,我们使用getAttribute()方法获取驱动程序名称,服务器版本和自动提交模式。

  1. $ php connection_attributes.php
  2. Driver: mysql
  3. Server version: 5.7.22-0ubuntu0.16.04.1
  4. Autocommit mode: 1

这是一个示例输出。

在以下示例中,我们打印列元数据。 列元数据通过getColumnMeta()方法检索。

column_metadata.php

  1. <?php
  2. $dsn = "mysql:host=localhost;dbname=mydb";
  3. $user = "user12";
  4. $passwd = "12user";
  5. $pdo = new PDO($dsn, $user, $passwd);
  6. $stm = $pdo->query("SELECT * FROM countries WHERE id=1");
  7. $col_meta = $stm->getColumnMeta(0);
  8. echo "Table name: {$col_meta["table"]}\n";
  9. echo "Column name: {$col_meta["name"]}\n";
  10. echo "Column length: {$col_meta["len"]}\n";
  11. echo "Column flags: {$col_meta["flags"][0]} {$col_meta["flags"][1]} \n";

在示例中,我们获取列表,名称,长度和标志。

  1. $ php column_metadata.php
  2. Table name: countries
  3. Column name: id
  4. Column length: 20
  5. Column flags: not_null primary_key

This is a sample output.

您可能也对以下相关教程感兴趣: PHP SQLite3 教程CakePHP 数据库教程Doctrine QueryBuilder教程PHP 文件系统函数Twig 教程PHP Faker 教程PHP 教程或列出所有 PHP 教程

在本教程中,我们使用 PHP PDO 处理 MySQL 数据库。