mysqli 面向對象 API,提供鏈式調用風格。cache_dir、cache_time),支持查詢結果自動緩存/失效。getOne、getRow、getAll 及對應緩存版本 cache_one、cache_row、cache_all。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(第二次命中緩存)
<?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));
}
}
die() 改為拋出 Exception,上層統一捕獲記錄日誌。prepare()/execute() 方法,防 SQL 注入。CacheInterface,支持 Redis、Memcached、APCu 等。query() 自動路由 SELECT 到從庫。mysqli::real_connect + MYSQLI_CLIENT_PERSISTENT。該類為中小型項目提供了開箱即用的數據庫訪問層,緩存機制可大幅降低重複查詢壓力。隨業務增長,建議逐步重構為基於 PDO 的 Repository 模式,引入 Doctrine DBAL 或成熟 ORM。