PHP PDO(PHP Data Objects)是PHP提供的一套统一的数据库访问抽象层,支持多种数据库类型,并且原生支持预处理语句,能够有效避免SQL注入问题,是PHP项目中进行数据库操作的首选方案。本文将通过一个完整的用户管理案例,讲解PDO从初始化到实现增删改查的全流程。
环境准备与数据库初始化
首先我们需要准备MySQL数据库,创建一个用户表用于存储测试数据,执行以下SQL语句创建表结构:
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `email` varchar(100) NOT NULL COMMENT '邮箱', `age` int(11) DEFAULT NULL COMMENT '年龄', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
PDO对象初始化
使用PDO操作数据库的第一步是创建PDO实例,需要传入数据库数据源名称(DSN)、用户名、密码等参数,同时建议开启异常模式,方便后续错误捕获。下面是初始化的代码示例:
<?php
// 数据库配置参数
$dbHost = '127.0.0.1';
$dbName = 'test_db';
$dbUser = 'root';
$dbPass = '123456';
$dbCharset = 'utf8mb4';
// 构建DSN字符串
$dsn = "mysql:host={$dbHost};dbname={$dbName};charset={$dbCharset}";
try {
// 创建PDO实例,开启异常模式
$pdo = new PDO($dsn, $dbUser, $dbPass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
echo "数据库连接成功";
} catch (PDOException $e) {
die("数据库连接失败:" . $e->getMessage());
}
?>
新增数据操作
使用PDO新增数据时,推荐使用预处理语句,通过占位符绑定参数,避免SQL注入。下面的代码实现向user表插入一条用户数据:
<?php
// 新增用户数据
$username = '张三';
$email = 'zhangsan@ipipp.com';
$age = 25;
// 预处理SQL语句,使用命名占位符
$sql = "INSERT INTO user (username, email, age) VALUES (:username, :email, :age)";
$stmt = $pdo->prepare($sql);
// 绑定参数并执行
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':age', $age, PDO::PARAM_INT);
if ($stmt->execute()) {
echo "新增成功,新增ID:" . $pdo->lastInsertId();
} else {
echo "新增失败";
}
?>
查询数据操作
查询操作分为查询单条数据和查询多条数据两种场景,PDO的fetch方法用于获取单条结果,fetchAll方法用于获取所有结果。下面是两种查询的示例:
<?php
// 查询单条用户数据,根据ID查询
$userId = 1;
$sql = "SELECT * FROM user WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':id', $userId, PDO::PARAM_INT);
$stmt->execute();
$user = $stmt->fetch();
if ($user) {
echo "查询到用户:{$user['username']},邮箱:{$user['email']}";
} else {
echo "未查询到对应用户";
}
echo "<br/>";
// 查询所有用户数据
$sql = "SELECT * FROM user";
$stmt = $pdo->query($sql);
$userList = $stmt->fetchAll();
echo "所有用户列表:<br/>";
foreach ($userList as $item) {
echo "ID:{$item['id']},用户名:{$item['username']},邮箱:{$item['email']}<br/>";
}
?>
更新数据操作
更新操作和新增操作类似,同样使用预处理语句绑定参数,下面是更新用户邮箱的示例:
<?php
// 更新用户邮箱
$userId = 1;
$newEmail = 'zhangsan_new@ipipp.com';
$sql = "UPDATE user SET email = :email WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':email', $newEmail, PDO::PARAM_STR);
$stmt->bindParam(':id', $userId, PDO::PARAM_INT);
if ($stmt->execute()) {
echo "更新成功,影响行数:" . $stmt->rowCount();
} else {
echo "更新失败";
}
?>
删除数据操作
删除操作同样需要做好参数绑定,避免误删数据,下面是删除指定ID用户的示例:
<?php
// 删除用户数据
$userId = 2;
$sql = "DELETE FROM user WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':id', $userId, PDO::PARAM_INT);
if ($stmt->execute()) {
echo "删除成功,影响行数:" . $stmt->rowCount();
} else {
echo "删除失败";
}
?>
事务处理示例
在需要保证多个操作原子性的场景下,可以使用PDO的事务功能,比如同时新增两个关联数据,要么都成功要么都失败。下面是事务处理的示例:
<?php
try {
// 开启事务
$pdo->beginTransaction();
// 第一个新增操作
$sql1 = "INSERT INTO user (username, email, age) VALUES ('李四', 'lisi@ipipp.com', 30)";
$pdo->exec($sql1);
// 第二个新增操作
$sql2 = "INSERT INTO user (username, email, age) VALUES ('王五', 'wangwu@ipipp.com', 28)";
$pdo->exec($sql2);
// 提交事务
$pdo->commit();
echo "事务执行成功,两条数据均新增完成";
} catch (Exception $e) {
// 出现异常回滚事务
$pdo->rollBack();
echo "事务执行失败,已回滚:" . $e->getMessage();
}
?>
核心注意事项
- 所有涉及用户输入的SQL操作都必须使用预处理语句,禁止直接拼接SQL字符串,避免SQL注入风险
- 初始化PDO时建议开启
PDO::ATTR_ERRMODE_EXCEPTION异常模式,方便统一捕获和处理数据库错误 - 使用
bindParam和bindValue时需要注意两者的区别,bindParam绑定的是变量引用,bindValue绑定的是变量的值 - 操作完成后不需要手动关闭PDO连接,PHP脚本执行结束会自动释放资源