ZetCode

PHP PDO 类

最后修改于 2025 年 4 月 19 日

PHP PDO(PHP Data Objects)类提供了一个在 PHP 中访问数据库的一致接口。它支持多种数据库系统,并使用相同的方法。

基本定义

PDO 是一个数据库访问层,提供了一种访问多个数据库的统一方法。它不提供特定于数据库的语法,但允许使用预处理语句。

语法:new PDO(string $dsn, string $username = null, string $password = null, array $options = null)。DSN 包含数据库类型、主机和数据库名称。

PDO 连接示例

这展示了如何使用 PDO 连接到 MySQL 数据库。

pdo_connect.php
<?php

declare(strict_types=1);

$host = 'localhost';
$dbname = 'testdb';
$user = 'user';
$pass = 'password';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Connected successfully";
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}

这创建了一个到 MySQL 数据库的连接。`setAttribute` 调用配置 PDO 在出错时抛出异常。始终在 PDO 操作中使用 try-catch。

PDO 查询示例

这演示了使用 PDO 执行一个简单的 SQL 查询。

pdo_query.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT * FROM users');
    
    while ($row = $stmt->fetch()) {
        echo "ID: {$row['id']}, Name: {$row['name']}\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这执行一个 SELECT 查询并逐行获取结果。`query` 方法返回一个 PDOStatement 对象。`fetch()` 从结果中检索下一行。

PDO 预处理语句

预处理语句可防止 SQL 注入并提高性能。

pdo_prepared.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
    $stmt->execute(['John Doe', 'john@example.com']);
    
    echo "New record created successfully";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这使用了带有位置占位符的预处理语句。`prepare` 方法创建语句模板。`execute` 使用提供的值运行它。

PDO 命名参数

命名参数使预处理语句更具可读性和可维护性。

pdo_named_params.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
    $stmt->execute(['email' => 'john@example.com']);
    
    $user = $stmt->fetch();
    if ($user) {
        echo "User found: {$user['name']}";
    } else {
        echo "User not found";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这在预处理语句中使用了命名参数。冒号前缀标识参数。`execute` 方法接受一个关联数组的值。

PDO 事务

事务确保多个操作作为一个单一的原子单元执行。

pdo_transaction.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $pdo->beginTransaction();
    
    $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");
    $pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE user_id = 2");
    
    $pdo->commit();
    echo "Transaction completed successfully";
} catch (PDOException $e) {
    $pdo->rollBack();
    echo "Transaction failed: " . $e->getMessage();
}

这演示了一个资金转账事务。`beginTransaction` 启动它。`commit` 使更改永久生效。`rollBack` 在失败时撤销更改。

PDO 获取模式

PDO 提供了从查询中获取结果集的不同方式。

pdo_fetch_modes.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Fetch as associative array
    $stmt = $pdo->query('SELECT * FROM users LIMIT 1');
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    
    // Fetch all as objects
    $stmt = $pdo->query('SELECT * FROM users');
    $users = $stmt->fetchAll(PDO::FETCH_OBJ);
    
    // Fetch column
    $stmt = $pdo->query('SELECT name FROM users');
    $names = $stmt->fetchAll(PDO::FETCH_COLUMN);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这展示了不同的获取模式。`FETCH_ASSOC` 返回关联数组。`FETCH_OBJ` 返回 `stdClass` 对象。`FETCH_COLUMN` 获取单个列。

最佳实践

来源

PHP PDO 文档

本教程介绍了 PHP PDO 类,并通过实际示例展示了不同场景下的数据库操作。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面有十多年的经验。

列出 所有 PHP PDO 函数