封装一个基于mysqli的php类库

封装了一个基于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);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值