用原生PHP封装一个通用的 PDO 类
以下是一个基于 PHP7.3.4+MySQL5.7 的 PDO 类的示例代码,封装了一些常见的数据库操作功能。
代码注释采用中文,代码中使用了 try-catch 来捕捉异常,在实际使用中需要根据具体情况加以修改和优化。
<?php
class PDOHelper {
/**
* 数据库连接对象
*/
private $pdo;
/**
* 数据库连接选项
*/
private $options = [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_EMULATE_PREPARES => false,
];
/**
* PDOHelper 构造函数
*
* @param string $dsn 数据源名称
* @param string $username 数据库用户名
* @param string $password 数据库密码
* @param array $options 数据库连接选项
*/
public function __construct(string $dsn, string $username, string $password, array $options = []) {
$this->options = $options + $this->options;
try {
$this->pdo = new PDO($dsn, $username, $password, $this->options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int) $e->getCode());
}
}
/**
* 执行 SQL 语句,返回结果集
*
* @param string $sql SQL 查询语句
* @param array $bindings 查询占位符对应的参数
*
* @throws PDOException 执行 SQL 语句失败时抛出异常
*
* @return array 结果集
*/
public function query(string $sql, array $bindings = []): array {
try {
$sth = $this->pdo->prepare($sql);
$sth->execute($bindings);
return $sth->fetchAll();
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int) $e->getCode());
}
}
/**
* 执行 SQL 语句,返回受影响的行数
*
* @param string $sql SQL 更新语句
* @param array $bindings 查询占位符对应的参数
*
* @throws PDOException 执行 SQL 语句失败时抛出异常
*
* @return int 受影响的行数
*/
public function execute(string $sql, array $bindings = []): int {
try {
$sth = $this->pdo->prepare($sql);
$sth->execute($bindings);
return $sth->rowCount();
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int) $e->getCode());
}
}
/**
* 启动一个事务
*
* @return bool 是否开启成功
*/
public function beginTransaction(): bool {
return $this->pdo->beginTransaction();
}
/**
* 提交事务
*
* @return bool 是否提交成功
*/
public function commit(): bool {
return $this->pdo->commit();
}
/**
* 回滚事务
*
* @return bool 是否回滚成功
*/
public function rollBack(): bool {
return $this->pdo->rollBack();
}
/**
* 获得最后插入行的 ID 或序列值
*
* @return string 最后插入行的 ID 或序列值
*/
public function lastInsertId(): string {
return $this->pdo->lastInsertId();
}
/**
* 关闭当前数据库连接
*
* @return void
*/
public function close(): void {
$this->pdo = null;
}
}
?>
使用示例:
<?php
$dsn = "mysql:host=localhost;dbname=database;charset=utf8mb4";
$username = "username";
$password = "password";
try {
$dbh = new PDOHelper($dsn, $username, $password);
// 查询
$sql = "SELECT * FROM users WHERE id = :id";
$bindings = [":id" => 1];
$result = $dbh->query($sql, $bindings);
print_r($result);
// 更新(事务)
$dbh->beginTransaction();
$sql1 = "UPDATE users SET name = :name WHERE id = :id";
$bindings1 = [":name" => "Jack", ":id" => 1];
$dbh->execute($sql1, $bindings1);
$sql2 = "UPDATE users SET email = :email WHERE id = :id";
$bindings2 = [":email" => "jack@example.com", ":id" => 1];
$dbh->execute($sql2, $bindings2);
$dbh->commit();
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
?>
注意:
在实际使用中,您需要将 $dsn、$username 和 $password 替换为您的实际值,并根据具体情况修改其他代码。例如,您可能会需要修改 $options 中的选项。
在 PHP 中,通过 try-catch 将异常处理存储在变量中,然后使用 Exception 类的 getMessage() 和 getCode() 方法来处理错误信息。这些信息也可以用于日志记录或调试。
建议使用预处理语句来减少 SQL 注入攻击的风险,可使得应用程序更加安全。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。