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

CodeIgniter 快取機制完整指南:資料庫快取、頁面快取與最佳實踐

     編輯:PHP 相關知識

CodeIgniter (CI) 內建兩層快取機制:**資料庫查詢快取** 減少 DB 負載,**頁面輸出快取** 達到近靜態頁速度。本文詳細說明設定、使用、清除策略與常見坑點。

一、資料庫快取 (Query Caching)

啟用三步驟

  1. 建立可寫入目錄:`mkdir -p application/cache/db && chmod 777 application/cache/db`
  2. 設定 `application/config/database.php`:
    $db['default']['cachedir'] = APPPATH . 'cache/db/';
    $db['default']['cache_on'] = TRUE; // 全域開啟
  3. 或程式碼動態控制:`$this->db->cache_on()` / `$this->db->cache_off()`

運作原理

  • 僅快取 **SELECT** 查詢 (產生結果集)。INSERT/UPDATE/DELETE 不快取。
  • 首次載入頁面:查詢結果序列化存檔 (`application/cache/db/{controller}+{method}/*.cache`)。
  • 後續請求:直接讀取快取檔,**完全繞過資料庫**,DB 使用率降為 0。
  • 快取檔**永不過期**,需手動刪除。

手動控制範例

<?php
$this->db->cache_on();
$query = $this->db->query("SELECT * FROM articles"); // 被快取

$this->db->cache_off();
$query = $this->db->query("SELECT * FROM user_session WHERE id = $uid"); // 不快取 (動態)

$this->db->cache_on();
$query = $this->db->query("SELECT * FROM categories"); // 再次快取
?>

清除快取

<?php
// 清除特定頁面 (依 URI 前兩段)
$this->db->cache_delete('blog', 'comments'); // 刪除 application/cache/db/blog+comments/

// 清除所有快取
$this->db->cache_delete_all();

// 注意:實測 cache_delete() 有時失效 (可能版本 Bug),cache_delete_all() 穩定。
?>

二、頁面快取 (Page Caching / Output Caching)

啟用方式

在**控制器方法內**任意位置呼叫:

$this->output->cache($minutes);
  • `$minutes`:快取分鐘數,支援小數 (如 `1/60` = 1 秒)。
  • 快取檔存放:`application/cache/{MD5_URI}.html`。
  • **僅快取 View 輸出** (經 `$this->load->view()` 或 `echo` 送至輸出緩衝區的內容)。
  • 需確保 `application/cache/` 可寫入。

運作流程

  1. 請求進入 → 檢查快取檔是否存在且未過期。
  2. **命中**:直接讀取檔案輸出,**不執行控制器邏輯**,極快。
  3. **未命中/過期**:執行控制器 → 捕獲輸出緩衝區 → 存檔 → 輸出。

停用與清除

  • 移除 `$this->output->cache()` 程式碼 → 新請求不再產生快取,舊檔自然過期刪除。
  • 立即清除:手動刪除 `application/cache/` 對應檔案。

三、常見問題與最佳實踐

問題解決方案
快取不生效檢查 `cachedir` 權限、`cache_on=TRUE`、是否為 SELECT 查詢
動態內容被快取 (如使用者名稱)用 `cache_off()` 包裹動態查詢,或改用片段快取 (第三方庫)
集群環境檔案快取不同步改用 Redis/Memcached 驅動 (CI3 需第三方庫,CI4 內建)
快取檔案過多導致 inode 耗盡定期 `cache_delete_all()`、調整目錄結構、改用記憶體快取
開發模式干擾設定 `$config['cache_query_string'] = FALSE` 避免查詢字串產生多份快取

四、進階:片段快取與第三方擴充

CI 原生不支援區塊級快取 (如側邊欄、導航列)。建議:

  • **CI3**:使用 `MatthiasMullie/Scrapbook`、`stensi/ci-cache` 或自寫 Helper 封裝 Redis/Memcached。
  • **CI4**:內建 `CacheInterface` 支援 File/Redis/Memcached/RedisCluster,支援 `save()`/`get()`/`delete()` 任意鍵值,天然支援片段快取。

總結建議

  • **資料庫快取**:適合靜態/半靜態報表、列表頁,配合 `cache_delete()` 於資料異動時清除。
  • **頁面快取**:適合極高流量、內容變動極低的頁面 (首頁、靜態文章)。**避免**用於有使用者狀態、表單、動態推薦的頁面。
  • **生產環境**:強烈建議將快取後端改為 **Redis/Memcached**,解決多伺服器同步、效能、inode 等問題。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved