跳至内容

PDO 与 MySQLi

这篇讲 PHP 连接 MySQL 数据库的两种主流方式——PDO 和 MySQLi——的选择依据、连接方法和基本查询操作。

PDO vs MySQLi

PHP 提供了两种操作 MySQL 的扩展,各有特点:

特性PDOMySQLi
数据库支持12 种数据库(MySQL、PostgreSQL、SQLite 等)仅 MySQL
API 风格纯面向对象面向过程 + 面向对象双模式
命名参数支持(:name不支持(仅 ?
未缓冲查询支持支持
推荐场景需要跨数据库兼容只用 MySQL 的老项目
推荐 PDO。它支持更多数据库类型,命名参数让预处理语句更可读,且换数据库只需改 DSN,无需重写代码。

PDO 连接

<?php
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$user = 'root';
$pass = '';

try {
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,   // 异常模式
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,  // 默认关联数组
        PDO::ATTR_EMULATE_PREPARES => false,            // 使用真正的预处理语句
    ]);
} catch (PDOException $e) {
    die('数据库连接失败:' . $e->getMessage());
}
?>
```sql

## PDO 查询

### 简单查询

```php
<?php
// 无参数的查询
$stmt = $pdo->query('SELECT id, name FROM users');
$users = $stmt->fetchAll();

foreach ($users as $user) {
    echo $user['name'] . '<br>';
}
?>

预处理语句(防 SQL 注入)

<?php
// 使用命名参数(推荐)
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => '[email protected]']);
$user = $stmt->fetch();

// 插入数据
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
$stmt->execute([
    'name' => '张三',
    'email' => '[email protected]',
]);
echo '最后插入 ID:' . $pdo->lastInsertId();
?>
```sql

### 获取结果的不同方式

```php
<?php
$stmt = $pdo->query('SELECT * FROM users');

$row = $stmt->fetch();       // 单行(关联数组)
$rows = $stmt->fetchAll();   // 所有行(二维数组)
$col = $stmt->fetchColumn(); // 单列值
$obj = $stmt->fetchObject(); // 单行(对象)
?>

MySQLi 连接与查询

MySQLi 提供面向过程和面向对象两种写法:

<?php
// 面向对象风格
$mysqli = new mysqli('localhost', 'root', '', 'test');

if ($mysqli->connect_error) {
    die('连接失败:' . $mysqli->connect_error);
}

// 预处理语句
$stmt = $mysqli->prepare('SELECT name, email FROM users WHERE id = ?');
$stmt->bind_param('i', $id);  // 'i' = integer
$id = 1;
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
?>
```text

## 一句话小结

PDO 是 PHP 数据库操作的推荐选择——跨数据库、命名参数、异常模式三大优势。无论用哪种方式,**始终使用预处理语句**——它是防御 SQL 注入的第一道防线。下一篇讲 [数据库安全与最佳实践](../02数据库查询最佳实践/)。
最后更新于