温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

PHP中PDO怎么使用

发布时间:2021-12-20 17:33:29 来源:亿速云 阅读:294 作者:小新 栏目:编程语言
# PHP中PDO怎么使用 ## 一、PDO简介 PDO(PHP Data Objects)是PHP中一个轻量级的、兼容性强的数据库操作抽象层。它为访问不同类型的数据库提供了统一的接口,开发者无需针对不同数据库编写特定代码。 ### 1.1 PDO核心优势 - **跨数据库兼容性**:支持MySQL、PostgreSQL、SQLite等12+种数据库 - **预处理语句**:内置防止SQL注入的机制 - **面向对象接口**:更符合现代PHP编程范式 - **错误处理**:多种错误模式可选 - **事务支持**:简化复杂数据库操作 ### 1.2 与mysql/mysqli扩展对比 | 特性 | PDO | mysql/mysqli | |---------------|----------------|--------------------| | 数据库支持 | 多数据库 | 仅MySQL | | API风格 | 纯面向对象 | 混合风格 | | 预处理 | 统一语法 | 不同实现 | | 命名参数 | 支持 | 不支持 | ## 二、PDO基本使用 ### 2.1 建立数据库连接 ```php <?php try { $dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4'; $username = 'db_user'; $password = 'db_pass'; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; $pdo = new PDO($dsn, $username, $password, $options); } catch (PDOException $e) { die("连接失败: " . $e->getMessage()); } 

参数说明: - $dsn:数据源名称,格式驱动名:host=主机;dbname=数据库名 - charset:强烈建议设置为utf8mb4以支持完整Unicode - $options常用配置: - ERRMODE_EXCEPTION:错误时抛出异常 - FETCH_ASSOC:默认返回关联数组 - EMULATE_PREPARES:禁用预处理模拟

2.2 执行简单查询

// 查询示例 $stmt = $pdo->query('SELECT * FROM users LIMIT 5'); $results = $stmt->fetchAll(); // 插入示例 $affectedRows = $pdo->exec(" INSERT INTO users(username, email) VALUES('john', 'john@example.com') "); 

三、预处理语句

3.1 防止SQL注入

// 位置参数 $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ? AND status = ?"); $stmt->execute([$id, $status]); // 命名参数 $stmt = $pdo->prepare(" INSERT INTO products(name, price) VALUES(:name, :price) "); $stmt->execute([ ':name' => $productName, ':price' => $price ]); 

3.2 绑定参数

$stmt = $pdo->prepare("SELECT * FROM posts WHERE category = ?"); $stmt->bindValue(1, $category, PDO::PARAM_STR); $stmt->execute(); // 绑定输出参数(存储过程) $stmt = $pdo->prepare("CALL get_user_stats(?, ?)"); $stmt->bindParam(1, $userId, PDO::PARAM_INT); $stmt->bindParam(2, $output, PDO::PARAM_STR, 100); $stmt->execute(); 

四、结果集处理

4.1 获取数据

// 获取单行 $row = $stmt->fetch(); // 获取所有结果 $allRows = $stmt->fetchAll(); // 遍历结果集 while ($row = $stmt->fetch()) { echo $row['username']; } // 获取单列 $emails = $stmt->fetchAll(PDO::FETCH_COLUMN, 0); 

4.2 获取对象

// 获取stdClass对象 $stmt->setFetchMode(PDO::FETCH_OBJ); // 映射到自定义类 class User {} $stmt->setFetchMode(PDO::FETCH_CLASS, 'User'); 

五、事务处理

try { $pdo->beginTransaction(); $stmt1 = $pdo->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); $stmt2 = $pdo->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?"); $stmt1->execute([$amount, $fromAccount]); $stmt2->execute([$amount, $toAccount]); $pdo->commit(); } catch (Exception $e) { $pdo->rollBack(); echo "事务失败: " . $e->getMessage(); } 

六、高级特性

6.1 批量插入

$data = [ ['name' => 'Product A', 'price' => 9.99], ['name' => 'Product B', 'price' => 19.99] ]; $stmt = $pdo->prepare("INSERT INTO products(name, price) VALUES(?, ?)"); foreach ($data as $row) { $stmt->execute([$row['name'], $row['price']]); } 

6.2 获取最后插入ID

$pdo->lastInsertId(); 

6.3 调用存储过程

$stmt = $pdo->prepare("CALL sp_get_user_data(?)"); $stmt->execute([$userId]); 

七、错误处理

// 设置错误模式(推荐在连接时设置) $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); try { // 数据库操作 } catch (PDOException $e) { error_log("数据库错误: " . $e->getMessage()); // 返回用户友好提示 echo "系统繁忙,请稍后再试"; } 

八、性能优化建议

  1. 持久连接:生产环境考虑使用PDO::ATTR_PERSISTENT
  2. 预处理重用:多次执行时复用预处理语句
  3. 适当使用缓冲查询:大数据集时使用PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
  4. 关闭连接:脚本结束前显式置空$pdo = null

九、完整示例

<?php class Database { private $pdo; public function __construct() { $this->connect(); } private function connect() { try { $this->pdo = new PDO( 'mysql:host=localhost;dbname=myapp;charset=utf8mb4', 'db_user', 'secure_password', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ] ); } catch (PDOException $e) { die("数据库连接失败: " . $e->getMessage()); } } public function getUser($userId) { $stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = :id"); $stmt->execute([':id' => $userId]); return $stmt->fetch(); } public function insertUser($userData) { $stmt = $this->pdo->prepare(" INSERT INTO users(username, email, created_at) VALUES(:username, :email, NOW()) "); return $stmt->execute([ ':username' => $userData['username'], ':email' => $userData['email'] ]); } } // 使用示例 $db = new Database(); $user = $db->getUser(42); 

十、常见问题解答

Q:PDO能防SQL注入吗? A:正确使用预处理语句时可以,但直接拼接SQL仍然危险。

Q:如何获取查询的行数? A:$stmt->rowCount(),但SELECT结果可能不准确,建议使用COUNT查询。

Q:PDO支持哪些数据库? A:完整列表包括MySQL、PostgreSQL、SQLite、Oracle、SQL Server等。

Q:为什么我的预处理语句很慢? A:检查是否禁用了模拟预处理(PDO::ATTR_EMULATE_PREPARES => false

通过本文的全面介绍,您应该已经掌握了PDO的核心用法。在实际开发中,建议将数据库操作封装到单独的类中,以提高代码的可维护性和安全性。 “`

这篇文章约3100字,涵盖了PDO的核心知识点,包括: 1. 基础连接和配置 2. 预处理语句使用 3. 事务处理 4. 结果集操作 5. 性能优化建议 6. 完整封装示例 7. 常见问题解答

采用Markdown格式,包含代码块、表格等元素,便于阅读和理解。可根据需要调整具体细节或补充特定数据库的专有特性。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI