在PHP中,使用PDO连接数据库并实现异常处理、批量插入数据以及插入和删除数据的操作可以通过以下步骤完成:
连接数据库并设置异常处理
<?php
// 定义数据库连接参数
$dbHost = 'localhost';
$dbName = 'your_database_name';
$dbUser = 'username';
$dbPass = 'password';
// 创建DSN字符串
$dsn = "mysql:host=$dbHost;dbname=$dbName;charset=utf8";
try {
// 创建PDO实例
$pdo = new PDO($dsn, $dbUser, $dbPass);
// 设置PDO错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 如果需要,设置其他属性如初始化命令(例如设置字符集)
// $pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8");
} catch (PDOException $e) {
// 捕获并输出数据库连接错误信息
die("Connection failed: " . $e->getMessage());
}
// 接下来进行数据操作
?>
批量插入数据
假设有一个 users
表,结构如下:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100)
);
批量插入数据的例子:
$dataToInsert = [
['username' => 'user1', 'email' => 'user1@example.com'],
['username' => 'user2', 'email' => 'user2@example.com'],
// 更多用户数据...
];
$sqlTemplate = "INSERT INTO users (username, email) VALUES (:username, :email)";
$stmt = $pdo->prepare($sqlTemplate);
foreach ($dataToInsert as $userData) {
$stmt->bindParam(':username', $userData['username']);
$stmt->bindParam(':email', $userData['email']);
try {
$stmt->execute();
} catch (PDOException $e) {
// 输出或处理插入失败的异常
echo "Error inserting data: " . $e->getMessage();
}
}
插入单条数据
$insertData = ['username' => 'new_user', 'email' => 'new_user@example.com'];
$sql = "INSERT INTO users (username, email) VALUES (:username, :email)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':username', $insertData['username']);
$stmt->bindParam(':email', $insertData['email']);
try {
$stmt->execute();
echo "New record created successfully";
} catch (PDOException $e) {
echo "Error inserting data: " . $e->getMessage();
}
删除数据
删除指定ID的数据:
$idToDelete = 123;
$sql = "DELETE FROM users WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':id', $idToDelete);
try {
$stmt->execute();
echo "Record deleted successfully";
} catch (PDOException $e) {
echo "Error deleting data: " . $e->getMessage();
}
请注意,在实际应用中,确保对用户输入进行适当的过滤和转义,以防止SQL注入攻击,并且在必要时使用事务处理以确保数据完整性。
PDO(PHP Data Objects)在处理数据库操作错误时提供了三种不同的模式:
-
PDO::ERRMODE_SILENT(静默模式,默认模式)
- 在这种模式下,当发生错误时,PDO不会抛出异常,也不会产生任何 PHP 错误警告。它仅将错误代码和信息保存到PDO对象内部,开发者需要通过
$pdo->errorCode()
和$pdo->errorInfo()
方法手动检查错误。
- 在这种模式下,当发生错误时,PDO不会抛出异常,也不会产生任何 PHP 错误警告。它仅将错误代码和信息保存到PDO对象内部,开发者需要通过
-
PDO::ERRMODE_WARNING
- 当选择此模式时,PDO在遇到错误时会产生
E_WARNING
级别的错误消息,并将其记录至PHP错误日志或显示在标准输出中(取决于错误报告级别)。同时,仍可通过上述方法获取错误详情。
- 当选择此模式时,PDO在遇到错误时会产生
-
PDO::ERRMODE_EXCEPTION
- 此模式下,PDO在遇到错误时会抛出一个
PDOException
异常。这意味着你可以通过try-catch
结构来捕获和处理这些异常,这通常被认为是一种更面向对象和更健壮的错误处理方式。
- 此模式下,PDO在遇到错误时会抛出一个
示例代码更改错误模式为异常模式:
try {
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// 处理数据库连接错误
echo 'Connection failed: ' . $e->getMessage();
}
在异常模式下,如果你尝试执行一个无效的SQL语句或者发生其他数据库错误,将会抛出异常,可以像下面这样处理:
try {
$stmt = $pdo->prepare('SELECT * FROM non_existent_table');
$stmt->execute();
// ... 操作数据 ...
} catch (PDOException $e) {
// 处理查询或其他数据库操作产生的异常
echo 'Database error: ' . $e->getMessage();
// 可能还需要记录错误日志或进行其他恢复操作
}
PDO(PHP Data Objects)中的事务(Transaction)允许你作为一个单独的工作单元执行一系列数据库操作,这些操作要么全部成功,要么全部失败。在事务处理中,如果其中一个操作失败,则所有已经执行的操作都会被回滚到事务开始前的状态,从而保持数据库的一致性。
在PDO中开启、执行和管理事务的基本步骤如下:
-
开启事务:
$pdo->beginTransaction(); // 开始一个新的事务
-
在事务内执行多个SQL操作:
try { $pdo->exec("INSERT INTO table1 (...) VALUES (...)"); $pdo->exec("UPDATE table2 SET column = value WHERE condition"); // 更多的数据库操作... // 如果所有的SQL语句都执行成功,提交事务 $pdo->commit(); } catch (PDOException $e) { // 如果在执行过程中有任何错误,回滚事务 $pdo->rollBack(); echo "Transaction failed: " . $e->getMessage(); }
-
提交事务:
commit()
方法用于提交事务,一旦提交,所有在事务块内的修改都将永久地写入数据库。
-
回滚事务:
rollBack()
方法用于取消事务中的所有更改,当事务中有错误发生或你想放弃这次操作时,调用该方法。
-
自动提交:
- 默认情况下,PDO连接会启用自动提交模式,即每执行一次SQL语句就会自动提交一次。但在进行事务处理时,通常会先禁用自动提交,然后手动控制事务的开始、提交和回滚。
-
示例代码片段:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 启用异常模式 $pdo->beginTransaction(); try { $stmt1 = $pdo->prepare("INSERT INTO some_table (...) VALUES (...)"); $stmt1->execute(); $stmt2 = $pdo->prepare("UPDATE another_table SET ... WHERE ..."); $stmt2->execute(); // ... 其他数据库操作 ... $pdo->commit(); // 如果这里没有抛出异常,事务将被提交 } catch (PDOException $e) { $pdo->rollBack(); // 如果有异常,事务将被回滚 echo "An error occurred during transaction: " . $e->getMessage(); }
事务功能的成功执行依赖于所使用的MySQL存储引擎是否支持事务处理,例如InnoDB引擎就支持事务,而MyISAM引擎则不支持事务。
在PHP中使用PDO(PHP Data Objects)查询数据库的基本步骤包括:
-
建立数据库连接:
<?php $servername = "127.0.0.1"; $username = "root"; $password = "a13834841085"; $dbname = "db_test"; try { $dsn = "mysql:host=$servername;port=3306;dbname=$dbname;charset=utf8"; $pdo = new PDO($dsn, $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "数据库连接成功!\n"; } catch (PDOException $e) { echo "数据库连接失败: " . $e->getMessage(); } ?>
-
执行SQL查询:
-
使用
query()
方法执行非预处理的SQL查询:$sql = "SELECT * FROM your_table"; $stmt = $pdo->query($sql); // 获取查询结果集 $results = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($results as $row) { print_r($row); }
-
使用
prepare()
和execute()
进行预处理查询(有助于防止SQL注入):$sql = "SELECT * FROM your_table WHERE id = :id"; $stmt = $pdo->prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); // 设置参数值 $id = 1; $stmt->execute(); // 获取单条结果 $result = $stmt->fetch(PDO::FETCH_ASSOC); echo "查询结果: "; print_r($result);
-
-
处理查询结果:
fetch()
或fetch(PDO::FETCH_ASSOC)
用于获取下一行作为关联数组。fetchAll()
则获取所有行作为一个二维数组,每一项对应表的一行数据。- 若需获取记录数量,可使用
rowCount()
方法(对于SELECT COUNT(*)
类型的查询尤其有用)。
-
关闭数据库连接(尽管在脚本结束时PDO连接通常会被自动关闭,但也可以手动关闭):
unset($pdo);
或者在使用完PDO对象之后显式关闭连接:
$pdo = null;
总结起来,一个完整的PDO查询示例可能如下所示:
<?php
require_once 'database.php';
$data = include 'database_configuration.php';
$dsn = "mysql:host={$data['db_address']};port={$data['db_port']};dbname={$data['db_name']};charset=utf8";
$username = $data['username'];
$password = $data['password'];
try {
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$id = 1;
$sql = "SELECT * FROM your_table WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$id]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result) {
echo "查询结果:\n";
print_r($result);
} else {
echo "没有找到匹配的数据!";
}
} catch (PDOException $e) {
echo "查询执行失败: " . $e->getMessage();
}
// 可选,手动关闭连接
$pdo = null;
?>
在PHP的PDO扩展中,PDOStatement::fetch()
方法用于从结果集中获取下一行数据。此方法有许多可选参数,允许开发者控制如何获取和格式化数据。以下是 fetch()
方法的基本签名及其参数说明:
mixed PDOStatement::fetch ([ int $fetch_style [, mixed $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )
-
$fetch_style:
- 定义获取数据的方式。它可以是以下常量之一:
PDO::FETCH_ASSOC
: 返回一个关联数组,其中的键是列名(字段名)。PDO::FETCH_NUM
: 返回一个索引数组,其中的索引是列的数字索引(从0开始)。PDO::FETCH_BOTH
: 默认选项,返回一个组合数组,包含索引和关联两种形式的键值对。PDO::FETCH_OBJ
: 返回一个stdClass对象,其中的属性名对应列名。PDO::FETCH_CLASS
: 返回指定类的一个实例,将列名映射到类的属性。PDO::FETCH_LAZY
: 延迟绑定模式,只有在访问时才获取列的值。- 还有其他如
PDO::FETCH_GROUP
,PDO::FETCH_UNIQUE
等模式,用于特殊需求。
- 定义获取数据的方式。它可以是以下常量之一:
-
$cursor_orientation:
- 当使用可滚动游标时,决定从哪个方向或位置获取下一行数据。
PDO::FETCH_ORI_NEXT
: 默认值,获取下一行(同fetch()
通常行为)。PDO::FETCH_ORI_PRIOR
: 获取上一行。PDO::FETCH_ORI_FIRST
: 移动到第一行并获取。PDO::FETCH_ORI_LAST
: 移动到最后一行并获取。PDO::FETCH_ORI_ABS
: 根据给定的绝对行号获取。PDO::FETCH_ORI_REL
: 根据相对于当前位置的相对行号获取。
- 当使用可滚动游标时,决定从哪个方向或位置获取下一行数据。
-
$cursor_offset:
- 当
$cursor_orientation
是PDO::FETCH_ORI_ABS
或PDO::FETCH_ORI_REL
时,此参数提供行号。如果是绝对位置,则表示从结果集的第一行开始计算的行号;如果是相对位置,则表示相对于当前游标位置的行数。
- 当
举例:
$stmt = $pdo->prepare("SELECT * FROM my_table");
$stmt->execute();
// 获取下一关联数组形式的行
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// 获取下一行并将其视为对象
$objRow = $stmt->fetch(PDO::FETCH_OBJ);
// 使用可滚动游标并在绝对位置3处获取行
$stmt = $pdo->prepare("SELECT * FROM my_table", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();
$rowAtPos3 = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, 3);
注意:并非所有数据库驱动都支持可滚动游标和所有 $cursor_orientation
和 $cursor_offset
参数组合。在实际应用中,请根据所使用的数据库适配器查阅文档以了解具体支持情况。