(唯一合适) PDO 教程

6次阅读

共计 2260 个字符,预计需要花费 6 分钟才能阅读完成。

PDO 是什么
首先思考, 为什么是选择 PDO
PDO 是一个数据访问抽象层 (Database Access Abstraction Layer). 抽象是双重的: 一个是众所周知但不太重要的. 另一个是模糊的但是是最重要的. 众所周知 PDO 为不同的数据库提供了统一的接口. 虽然这个功能本身很庞大, 但是对于固定程序来说不是过于重要的事情, 基本所有的程序都是使用统一的后端数据库. 尽管有一些谣言, 但是通过改变单行 PDO 配置来切换后端数据库是不可能的 - 由于不同的 SQL 风格 (为此, 需要使用像 DQL 这样的平均查询语言). 因此对于普通的 LAMP 开发者来说, 这一点是微不足道的, 并且对他而言, PDO 只是熟悉的 mysql(i)_query() 函数的另一个更复杂版本. 但实际上它不是, 它有丰富的其他功能.PDO 不仅抽象了数据库 API, 还抽象了基本操作, 否则必须在每个应用程序中重复数百次, 使您的代码非常 WET. 不同于 mysql 和 mysqli , 两个都不能直接使用低级裸 APIs( 但仅作为某些更高级别抽象层的构建材料), PDO 就是这样的抽象. 虽然仍是不完整的, 但是至少可用. 真正的 PDO 好处是:

安全性 (可用的准备语句)
可用性 (许多辅助函数可以自动执行日常操作)
可重用性 (用于访问大量数据库的统一 API, 从 SQLITE 到 oracle)

请注意, 尽管 PDO 是原生数据库驱动程序中最好的, 但对于现代 WEB 应用程序来说, 请考虑将使用有查询构建器的 ORM 或者与其他更高抽象级别的库一起使用, 只是偶尔使用原生的 PDO. 好的 ORM 比如 Doctrine, Eloquent, RedBean 和 Yii::AR. Aura.SQL 是具有很多附加功能的使用 PDO 包装器的一个很好的例子. 无论哪种方式, 首先要了解基本工具是件好事. 那么, 让我们开始吧:
connection DSN
PDO 有一个叫 DSN 的预想接方式. 它并不复杂 -PDO 需要你在三个不同的位置输入不同的配置, 而不是一个简单的选项列表.

database driver, host, db(schema) name 和 charset, 以及不常使用的 port 和 unix_socket 设置 DSN

user_name 和 password 设置构造方法
其他所有的配置在 options 数组

其中 DSN 是以分号分隔的字符串, 由 param=value 键值对组成, 从驱动程序名称和冒号开始:
mysql:host=localhost;dbname=test;port=3306;charset=utf8mb4
driver^ ^colon ^param=value pair ^semicolon
注意, 遵循正确的格式是非常重要的 - DSN 中不能使用 空格, 引号, 和其他的符号, 只能使用参数, 值和定界符. 就像手册上展示的.
这里有一个例子:
$host = ‘127.0.0.1’;
$db = ‘test’;
$pass = ‘root’;
$charset = ‘utf8mb4’;

$dsn = “mysql:host={$host};dbnamej={$db};charset={$charset}”;
$options = [
PDO::ATR_ERRMODE => PDO::ERRMODE_EXECPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new \PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
}
设置了所有上述变量属性, 我们将在 $pdo 变量中得到一个正确的 PDO 实例. 使用旧 mysql 扩展用户重要通知

不同于 mysql_* 函数, 可以在代码的任意位置使用, pdo 实例被存储在一个变量中, 那就意味着只能在函数内部进行访问. 因此, 必须通过函数参数传递或使用更高级的技术, 比如 IOC 容器.
连接只用创建一次. 不要在函数, 类构造函数创建连接, 否则, 会创建多个连接, 最终导致数据库服务宕机. 因此必须创建唯一的 PDO 实例, 让整个脚本使用.(适用于 FPM 模式)
通过 DSN 设置字符集是非常重要的 - 这是唯一正确的方式因为它会告诉 PDO 哪个字符集会被使用. 因此, 忘记通过 Query 运行 SET NAMES 或者通过 PDO::MYSQL_ATTR_INIT_COMMAND. 只有当 PHP 版本过低时 (低于 5.3.6), 才可以使用 SET NAMES 查询, 并且关闭仿真模式.

更多关于连接的内容可以在 连接 MySQL 查看
运行查询 PDO::query()
使用 PDO 有两种方式运行查询. 如果查询中没有使用变量, 可以使用 PDO::query 方法. 它会运行查询并返回一个 PDOStatement 类的对象, 该类与 mysql_query 返回的资源大致相同, 特别时从中获取实际记录的操作:
$stmt = $pdo->query(‘SELECT name FROM users’);
while ($row = $stmt->fetch()) {
echo $row[‘name’] . “\n”;
}
并且 query() 方法允许我们使用一个整洁的方法连接 SELECT 查询, 如下所示.
预处理, 防止 SQL 注入
放弃熟悉的 mysql_query() 函数 并进入严格数据对象领域的主要原因是 PDO 已经准备好了开箱即用的预处理语句. 如果要在语句中使用变量, 预处理语句是唯一正确运行的方式. 它如此重要的原因在 The Hitchhiker’s Guide to SQL Injection prevention. 有详细的解释.

正文完
 0