PHP PDO

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

$ php -v
php -v
PHP 8.1.2 (cli) (built: Aug  8 2022 07:28:23) (NTS)
...

我们使用PHP版本8.1.2。

PHPPDO

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

PHPPDO类

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

MySQL数据库

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

DROP TABLE IF EXISTS countries;
CREATE TABLE countries(id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255), population INT);

INSERT INTO countries(name, population) VALUES('China', 1382050000);
INSERT INTO countries(name, population) VALUES('India', 1313210000);
INSERT INTO countries(name, population) VALUES('USA', 324666000);
INSERT INTO countries(name, population) VALUES('Indonesia', 260581000);
INSERT INTO countries(name, population) VALUES('Brazil', 207221000);
INSERT INTO countries(name, population) VALUES('Pakistan', 196626000);
INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
INSERT INTO countries(name, population) VALUES('Bangladesh', 162099000);
INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
INSERT INTO countries(name, population) VALUES('Russia', 146838000);
INSERT INTO countries(name, population) VALUES('Japan', 126830000);

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

PHPPDO查询

PDOquery在单个函数调用中执行SQL语句,返回语句返回的结果集(如果有的话)。

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

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

$version = $stm->fetch();

echo $version[0] . PHP_EOL;

该示例返回MySQL的版本。

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

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

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

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

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

$version = $stm->fetch();

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

echo $version[0] . PHP_EOL;

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

$ php version.php
8.0.29-0ubuntu0.22.04.2

这是输出。

PHPPDO执行

PDOexec执行SQL语句并返回受影响的行数。

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

$id = 12;

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

echo "The statement affected $nrows rows\n";

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

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

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

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

我们打印删除的行数。

PHPPDO获取方式

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

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

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

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

foreach($rows as $row) {

    printf("$row[0] $row[1] $row[2]\n");
}

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

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

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

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

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

foreach($rows as $row) {

    printf("$row[0] $row[1] $row[2]\n");
}

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

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

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

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

foreach($rows as $row) {

    printf("{$row['id']} {$row['name']} {$row['population']}\n");
}

在这个例子中,我们以关联数组的形式获取数据。

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

fetchAll方法中,我们使用了PDO::FETCH_ASSOC风格。

PHPPDO参数绑定

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

PDO包含bindParambindValue方法来创建参数化查询。

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

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "root";
$passwd = "andrea";

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

$id = 12;

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

$row = $stm->fetch(PDO::FETCH_ASSOC);

echo "Id: " . $row['id'] . PHP_EOL;
echo "Name: " . $row['name'] . PHP_EOL;
echo "Population: " . $row['population'] . PHP_EOL;

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

$id = 12;

假设此输入来自用户。

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

select语句从表中获取特定行。我们使用bindValue将值绑定到问号占位符。

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

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

$id = 12;

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

$row = $stm->fetch(PDO::FETCH_ASSOC);

echo "Id: " . $row['id'] . PHP_EOL;
echo "Name: " . $row['name'] . PHP_EOL;
echo "Population: " . $row['population'] . PHP_EOL;

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

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

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

PHPPDO最后插入的行ID

PDOlastInsertId方法返回最后插入的行ID。

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

$sql = "CREATE TABLE words(id INT PRIMARY KEY AUTO_INCREMENT,
    word VARCHAR(255))";

$ret = $pdo->exec($sql);
$pdo->exec("INSERT INTO words(word) VALUES ('pen')");
$pdo->exec("INSERT INTO words(word) VALUES ('bum')");
$pdo->exec("INSERT INTO words(word) VALUES ('hum')");
$pdo->exec("INSERT INTO words(word) VALUES ('den')");

$rowid = $pdo->lastInsertId();

echo "The last inserted row id is: $rowid\n";

在示例中,我们创建了一个新表。创建表后,我们通过lastInsertId找到最后插入的Id。

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

这是输出。

mysql> select * from words;
+----+------+
| id | word |
+----+------+
|  1 | pen  |
|  2 | bum  |
|  3 | hum  |
|  4 | den  |
+----+------+
4 rows in set (0.01 sec)

我们验证数据。

PHPPDO交易

事务是对一个或多个数据库中的数据进行数据库操作的原子单元。一个事务中所有SQL语句的效果可以全部提交到数据库,也可以全部回滚。

PDObeginTransaction启动一个新事务。PDOcommit提交事务。PDOrollback回滚事务。

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

try {

    $pdo->beginTransaction();
    $stm = $pdo->exec("INSERT INTO countries(name, population) VALUES ('Iraq', 38274000)");
    $stm = $pdo->exec("INSERT INTO countries(name, population) VALUES ('Uganda', 37673800)");

    $pdo->commit();

} catch(Exception $e) {

    $pdo->rollback();
    throw $e;
}

在示例中,我们向数据库表中添加了两个新国家/地区。插入语句放在一个事务中:要么执行两个插入,要么不执行。

} catch(Exception $e) {

    $pdo->rollback();
    throw $e;
}

如果出现异常,我们会回滚事务:没有数据写入数据库。我们抛出异常,以便异常处理以通常的方式继续。

PHPPDO获取元数据

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

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

$stm = $pdo->query("SELECT name, population FROM countries WHERE id=1");

$ncols = $stm->columnCount();

echo "The result set contains $ncols columns\n";

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

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

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
$server_version = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
$autocommit_mode = $pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);

echo "Driver: $driver\n";
echo "Server version: $server_version\n";
echo "Autocommit mode: $autocommit_mode\n";

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

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

这是一个示例输出。

在下面的示例中,我们打印列元数据。使用getColumnMeta方法检索列元数据。

<?php

$dsn = "mysql:host=localhost;dbname=mydb";
$user = "user12";
$passwd = "12user";

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

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

$col_meta = $stm->getColumnMeta(0);

echo "Table name: {$col_meta["table"]}\n";
echo "Column name: {$col_meta["name"]}\n";
echo "Column length: {$col_meta["len"]}\n";
echo "Column flags: {$col_meta["flags"][0]} {$col_meta["flags"][1]} \n";

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

$ php column_metadata.php
Table name: countries
Column name: id
Column length: 20
Column flags: not_null primary_key

这是一个示例输出。

在本教程中,我们使用PDO在PHP中编写了数据库。

列出所有PHP教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏