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

CodeIgniter 整合 Smarty 模板引擎完實作指南 (無縫整合版)

     編輯:PHP 綜合知識

為什麼整合 Smarty?

CI 內建視圖功能簡單但缺乏模板繼承、區塊覆蓋、緩存、修飾符、安全轉義** 等進階功能。Smarty 作為成熟 PHP 模板引擎,提供完整模板系統,與 CI 整合後可保持 $this->assign()、$this->display() 習慣用法,實現「無縫切換」。

版本資訊

  • CodeIgniter 3.x (亦適用 2.x 微調)
  • Smarty 3.x / 4.x (本文以 3.1 為例)

整合步驟

1. 安裝 Smarty 庫

下載 Smarty 並放入 application/libraries/Smarty/,或用 Composer:

composer require smarty/smarty

目錄結構:

application/
├── libraries/
│   └── Smarty/
│       ├── Smarty.class.php
│       ├── sysplugins/
│       └── plugins/
├── config/
│   └── smarty.php          # Smarty 專用配置
└── core/
    └── MY_Controller.php   # 擴展控制器

2. 建立 CI_Smarty 封裝類

application/libraries/Ci_smarty.php

class Ci_smarty extends Smarty {
    protected $ci;
    
    public function __construct() {
        parent::__construct();
        $this->ci =& get_instance();
        
        // 載入配置
        $this->ci->config->load('smarty');
        
        // 套用配置
        $this->setTemplateDir($this->ci->config->item('template_dir'));
        $this->setCompileDir($this->ci->config->item('compile_dir'));
        $this->setCacheDir($this->ci->config->item('cache_dir'));
        $this->setConfigDir($this->ci->config->item('config_dir'));
        
        $this->caching = (bool)$this->ci->config->item('caching');
        $this->cache_lifetime = (int)$this->ci->config->item('cache_lifetime');
        $this->left_delimiter = $this->ci->config->item('left_delimiter');
        $this->right_delimiter = $this->ci->config->item('right_delimiter');
        
        // 註冊 CI 專用修飾符/函數
        $this->registerPlugin('modifier', 'base_url', function($uri) {
            return $this->ci->config->base_url($uri);
        });
        $this->registerPlugin('modifier', 'site_url', function($uri) {
            return $this->ci->config->site_url($uri);
        });
    }
}

3. Smarty 配置檔

application/config/smarty.php

$config['template_dir'] = APPPATH . 'views/';
$config['compile_dir'] = FCPATH . 'storage/smarty/compile/';
$config['cache_dir'] = FCPATH . 'storage/smarty/cache/';
$config['config_dir'] = APPPATH . 'config/smarty/';

$config['caching'] = false; // true 開啟模板緩存
$config['cache_lifetime'] = 3600;

$config['left_delimiter'] = '{';
$config['right_delimiter'] = '}';

// 確保目錄存在且可寫
foreach (['compile_dir', 'cache_dir'] as $key) {
    $dir = $config[$key];
    if (!is_dir($dir)) mkdir($dir, 0755, true);
}

4. 自動載入

application/config/autoload.php

$autoload['libraries'] = ['ci_smarty'];

5. 擴展核心控制器 (關鍵:無縫 API)

application/core/MY_Controller.php

class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
    }
    
    // 代理 assign() 到 Smarty
    public function assign($key, $val = null) {
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                $this->ci_smarty->assign($k, $v);
            }
        } else {
            $this->ci_smarty->assign($key, $val);
        }
    }
    
    // 代理 display() 到 Smarty
    public function display($template) {
        // 自動補全副檔名
        if (pathinfo($template, PATHINFO_EXTENSION) === '') {
            $template .= '.tpl';
        }
        $this->ci_smarty->display($template);
    }
    
    // 額外:fetch() 支援
    public function fetch($template) {
        if (pathinfo($template, PATHINFO_EXTENSION) === '') {
            $template .= '.tpl';
        }
        return $this->ci_smarty->fetch($template);
    }
}

使用範例

控制器

class Welcome extends MY_Controller {
    public function index() {
        $this->assign('title', '首頁標題');
        $this->assign('user', ['name' => 'Admin', 'role' => 'super']);
        $this->assign('items', [
            ['id' => 1, 'name' => '項目一'],
            ['id' => 2, 'name' => '項目二'],
        ]);
        $this->display('welcome');
    }
}

模板 application/views/welcome.tpl

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{$title}</title>
</head>
<body>
    <h1>歡迎,{$user.name} ({$user.role})</h1>
    
    <ul>
    {foreach $items as $item}
        <li>{$item.id|base_url} - {$item.name}</li>
    {/foreach}
    </ul>
    
    <!-- 區塊繼承範例 -->
    {block name="sidebar"}
        <div class="sidebar">預設側邊欄</div>
    {/block}
</body>
</html>

子模板繼承 application/views/admin/layout.tpl

<html>
<head><title>{$title}</title></head>
<body>
    <header>管理後台</header>
    <div class="layout">
        <aside>{block name="sidebar"}{/block}</aside>
        <main>{block name="content"}{/block}</main>
    </div>
</body>
</html>
<!-- application/views/admin/dashboard.tpl -->
{extends file="admin/layout.tpl"}
{block name="sidebar"}
    <nav>管理選單...</nav>
{/block}
{block name="content"}
    <h2>儀表板</h2> ...
{/block}

進階功能啟用

模板緩存

// 配置開啟
$config['caching'] = true;
$config['cache_lifetime'] = 1800; // 30 分鐘

// 控制器中動態控制
$this->ci_smarty->caching = true;
$this->ci_smarty->cache_lifetime = 300;
$this->display('heavy_page');

資料庫驅動模板 (進階)

實作 Smarty_Resource_Custom 從 DB 讀取模板內容,配合 $smarty->registerResource(),實現後台可視化編輯模板。

安全性:自動轉義

// Smarty 3 預設啟用自動轉義
$config['auto_escape'] = true; // 模板中 {$var} 自動 htmlspecialchars
// 需原始輸出用 {$var nofilter} 或 {$var|escape:'htmlall'}

常見問題排查

問題解決
找不到 Smarty.class.php檢查 libraries/Smarty/ 目錄結構、autoload 大小寫
compile_dir 權限錯誤chmod 775 storage/smarty/compile/、擁有者 www-data
模板變數不顯示確認 assign() 在 display() 前呼叫、變數名拼寫
繼承 {extends} 不生效Smarty 3 需啟用 $smarty->compile_check = true、路徑正確
修飾符 base_url 失效檢查 Ci_smarty 建構子 registerPlugin 註冊

總結

透過 Ci_smarty 封裝 + MY_Controller 代理 assign/display,實現 CI 與 Smarty **零學習成本整合**:控制器代碼完全不變,視圖檔案僅改為 .tpl 並享受 Smarty 全功能 (繼承、緩存、修飾符、安全轉義、沙箱)。此方案生產驗證穩定,是 CI 專案升級模板層的首選。

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