首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

帶緩存功能的 PHP mysqli 數據庫操作類:設計與使用指南

     編輯:PHP 相關知識

類特性概覽

  • 封裝 mysqli 面向對象 API,提供鏈式調用風格。
  • 內建文件緩存機制(cache_dir、cache_time),支持查詢結果自動緩存/失效。
  • 統一異常處理:查詢失敗直接輸出錯誤並終止(可改為拋出異常)。
  • 支持 getOne、getRow、getAll 及對應緩存版本 cache_one、cache_row、cache_all。
  • 內建 SQL 參數轉義 escape(),支持數組批量轉義。

核心代碼結構

<?php
class db_mysqli {
    protected $mysqli;
    protected $sql;
    protected $rs;
    protected $query_num = 0;
    protected $fetch_mode = MYSQLI_ASSOC;
    protected $cache_dir = './cache/';
    protected $cache_time = 1800; // 秒

    public function __construct($dbhost, $dbuser, $dbpass, $dbname) {
        $this->mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
        if (mysqli_connect_errno()) {
            die('

' . mysqli_connect_error() . '

'); } $this->mysqli->set_charset("utf8"); } public function __destruct() { $this->free(); $this->close(); } // 核心查詢方法 public function query($sql, $limit = null) { $sql = $this->getQuerySql($sql, $limit); $this->sql = $sql; $this->rs = $this->mysqli->query($sql); if (!$this->rs) { die('

' . $this->mysqli->error . '

'); } $this->query_num++; return $this->rs; } // 獲取單值 public function getOne($sql) { $this->query($sql, 1); $this->fetch_mode = MYSQLI_NUM; $row = $this->fetch(); $this->free(); return $row[0]; } // 獲取單行 public function getRow($sql, $fetch_mode = MYSQLI_ASSOC) { $this->query($sql, 1); $this->fetch_mode = $fetch_mode; $row = $this->fetch(); $this->free(); return $row; } // 獲取所有行 public function getAll($sql, $limit = null, $fetch_mode = MYSQLI_ASSOC) { $this->query($sql, $limit); $this->fetch_mode = $fetch_mode; $all_rows = []; while ($rows = $this->fetch()) { $all_rows[] = $rows; } $this->free(); return $all_rows; } // 緩存封裝 protected function get_cache($sql, $method) { include_once './cache.php'; // 需自行實現 Cache 類 $cache = new Cache($this->cache_dir, $this->cache_time); $cache_file = md5($sql . $method); $res = $cache->get_cache($cache_file); if (!$res) { $res = $this->$method($sql); $cache->set_cache($cache_file, $res); } return $res; } public function cache_one($sql) { return $this->get_cache($this->getQuerySql($sql, 1), 'getOne'); } public function cache_row($sql) { return $this->get_cache($this->getQuerySql($sql, 1), 'getRow'); } public function cache_all($sql, $limit = null) { return $this->get_cache($this->getQuerySql($sql, $limit), 'getAll'); } // 工具方法 public function insert_id() { return $this->mysqli->insert_id(); } public function escape($str) { /* ... 數組遞歸轉義 ... */ } // ... getQuerySql, fetch, free, close 等內部方法 } ?>

使用示例

require_once 'db_mysqli.php';

$db = new db_mysqli('localhost', 'root', '111222', 'dict');
$db->set_cache_time(10);        // 10 秒緩存
$db->set_cache_dir('./cache/sql/');

$sql = "SELECT * FROM words ORDER BY word_id LIMIT 10, 10";

// 直接查詢(每次執行 SQL)
$res1 = $db->get_all($sql);

// 緩存查詢(首次執行 SQL,後續命中緩存)
$res2 = $db->cache_all($sql);

echo "查詢次數: " . $db->query_num() . "<br>"; // 輸出 1(第二次命中緩存)

Cache 類參考實現(簡易文件緩存)

<?php
// cache.php
class Cache {
    private $dir;
    private $expire;

    public function __construct($dir, $expire) {
        $this->dir = rtrim($dir, '/') . '/';
        $this->expire = $expire;
        if (!is_dir($this->dir)) mkdir($this->dir, 0755, true);
    }

    public function get_cache($key) {
        $file = $this->dir . $key . '.cache';
        if (!file_exists($file)) return false;
        if (time() - filemtime($file) > $this->expire) {
            unlink($file);
            return false;
        }
        return unserialize(file_get_contents($file));
    }

    public function set_cache($key, $data) {
        $file = $this->dir . $key . '.cache';
        file_put_contents($file, serialize($data));
    }
}

改進建議(生產環境)

  1. 異常化錯誤處理:將 die() 改為拋出 Exception,上層統一捕獲記錄日誌。
  2. 預處理語句支持:新增 prepare()/execute() 方法,防 SQL 注入。
  3. 緩存驅動可插拔:定義 CacheInterface,支持 Redis、Memcached、APCu 等。
  4. 緩存鍵策略優化:引入表名、WHERE 條件哈希,避免不同查詢碰撞。
  5. 讀寫分離:構造函數接受主從配置,query() 自動路由 SELECT 到從庫。
  6. 連接池/持久連接:高併發場景啟用 mysqli::real_connect + MYSQLI_CLIENT_PERSISTENT。

總結

該類為中小型項目提供了開箱即用的數據庫訪問層,緩存機制可大幅降低重複查詢壓力。隨業務增長,建議逐步重構為基於 PDO 的 Repository 模式,引入 Doctrine DBAL 或成熟 ORM。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved