封装了一个基于mysqli的类库,这个类库现在包含了对数据库的基本操作:插入、查询、更新、删除数据,并且采用了预处理语句和参数绑定的方式来避免SQL注入攻击。它还能对表名和列名进行基本验证,避免因错误的表名或列名导致的问题。如果在执行数据库操作时发生错误,类库会将错误信息记录到一个日志文件中。
<?php
/**
* Database类,用于与MySQL数据库进行交互。
*/
class Database {
// 数据库凭证
private $host = 'localhost';
private $user = 'mytest';
private $password = 'FmFhKyEZiyNYF37R';
private $database = 'mytest';
private $connection; // 表示数据库连接的MySQLi对象
private $logFile = './logfile.log'; // 错误日志文件路径
/**
* 构造函数,建立数据库连接。
*/
public function __construct() {
$this->connectDB();
}
/**
* 使用MySQLi建立数据库连接。
*/
public function connectDB() {
$this->connection = new mysqli($this->host, $this->user, $this->password, $this->database);
// 连接错误处理
if ($this->connection->connect_error) {
$this->logError('连接错误 (' . $this->connection->connect_errno . ') ' . $this->connection->connect_error);
die('连接错误');
}
}
/**
* 对表名和列名进行简单的验证。
*/
private function validateName($name) {
return preg_match('/^[a-z0-9_]+$/', $name);
}
/**
* 准备并执行SQL查询。使用预处理语句和参数绑定增加安全性。
*/
private function prepareAndExecute($sql, $params) {
$stmt = $this->connection->prepare($sql);
if (!$stmt) {
$this->logError('准备失败: (' . $this->connection->errno . ') ' . $this->connection->error);
throw new Exception('准备失败');
}
if (!$stmt->bind_param(str_repeat('s', count($params)), ...$params)) {
$this->logError('参数绑定失败: (' . $stmt->errno . ') ' . $stmt->error);
throw new Exception('参数绑定失败');
}
if (!$stmt->execute()) {
$this->logError('执行失败: (' . $stmt->errno . ') ' . $stmt->error);
throw new Exception('执行失败');
}
return $stmt;
}
/**
* 向指定的表插入一行新的数据。使用预处理语句和参数绑定增加安全性。
*/
public function insert($table, $data) {
if (!is_array($data)) {
throw new InvalidArgumentException('$data必须为数组');
}
if (!$this->validateName($table)) {
throw new InvalidArgumentException('无效的表名');
}
$keys = array_keys($data);
foreach ($keys as $key) {
if (!$this->validateName($key)) {
throw new InvalidArgumentException('无效的列名');
}
}
$keysStr = implode(',', $keys);
$placeholders = str_repeat('?,', count($data) - 1) . '?';
$sql = "INSERT INTO $table ($keysStr) VALUES ($placeholders)";
return $this->prepareAndExecute($sql, array_values($data));
}
// 对select, update, delete等方法做类似的处理...
/**
* 记录错误信息到日志文件。
*/
private function logError($error) {
file_put_contents($this->logFile, date('Y-m-d H:i:s') . " - " . $error . PHP_EOL, FILE_APPEND);
}
/**
* 从指定的表中选择数据。使用预处理语句和参数绑定增加安全性。
*/
public function select($table, $where = '', $params = []) {
if (!$this->validateName($table)) {
throw new InvalidArgumentException('无效的表名');
}
$sql = "SELECT * FROM $table";
if (!empty($where)) {
$sql .= " WHERE $where";
}
return $this->prepareAndExecute($sql, $params);
}
/**
* 更新指定表中的数据。使用预处理语句和参数绑定增加安全性。
*/
public function update($table, $data, $where, $params = []) {
if (!is_array($data)) {
throw new InvalidArgumentException('$data必须为数组');
}
if (!$this->validateName($table)) {
throw new InvalidArgumentException('无效的表名');
}
$keys = array_keys($data);
foreach ($keys as $key) {
if (!$this->validateName($key)) {
throw new InvalidArgumentException('无效的列名');
}
}
$updateStr = implode('=?,', $keys) . '=?';
$sql = "UPDATE $table SET $updateStr WHERE $where";
$params = array_merge(array_values($data), $params);
return $this->prepareAndExecute($sql, $params);
}
/**
* 从指定的表中删除数据。使用预处理语句和参数绑定增加安全性。
*/
public function delete($table, $where, $params = []) {
if (!$this->validateName($table)) {
throw new InvalidArgumentException('无效的表名');
}
$sql = "DELETE FROM $table WHERE $where";
return $this->prepareAndExecute($sql, $params);
}
/**
* 析构函数,在Database类的实例不再需要时调用。关闭数据库连接。
*/
public function __destruct() {
$this->connection->close();
}
}
本地有测试数据表users
,数据表结构为
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`username` varchar(255) NOT NULL COMMENT '账号',
`password` varchar(255) NOT NULL COMMENT '密码'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `users` ADD PRIMARY KEY (`id`);
ALTER TABLE `users` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
以下是提供的相关调用示例,
db = new Database();
// 新增
$data = [
'username' => 'exampleuser',
'password' => 'examplepassword',
];
$res=$db->insert('users', $data);
print_r($res);
//查询
$stmt = $db->select('users', 'username = ?', ['exampleuser']);
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
print_r($row);
}
// 更新的数据
$data = [
'password' => 'newpassword',
];
// Where子句中的条件
$where = 'id = ?';
// Where子句中的参数
$params = [28];
// 调用 update 方法
$db->update('users', $data, $where, $params);
// 删除数据
$stmt=$db->delete('users', 'id = ?', [30]);
print_r($stmt);