CodeIgniter 原生 config 僅支援靜態文件配置,無法滿足「後台動態修改、分組管理、按需加載」等實際需求。本文提供一個 Setting 庫,基於數據庫存儲配置,支援自動加載、分組查詢、單項讀寫、增刪改查,零侵入式集成到 CI 專案。
CREATE TABLE `system_settings` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`key` varchar(64) NOT NULL DEFAULT '',
`value` mediumtext NOT NULL,
`group` varchar(55) NOT NULL DEFAULT 'site',
`autoload` enum('no','yes') NOT NULL DEFAULT 'yes',
PRIMARY KEY (`id`,`key`),
KEY `name` (`key`),
KEY `autoload` (`autoload`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
autoload=yes:系統啟動時自動寫入 CI $this->config,可直接用 $this->config->item('key') 讀取。autoload=no:臨時配置,需呼叫 $this->setting->item('key') 讀取。<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Setting {
protected $CI;
protected $table;
protected $cache = [];
protected $autoloaded = false;
public function __construct() {
$this->CI =& get_instance();
$this->table = $this->CI->config->item('settings_table');
$this->autoload();
}
// 自動加載 autoload=yes 的配置
public function autoload() {
if ($this->autoloaded) return $this->cache;
if (!$this->CI->db->table_exists($this->table)) return false;
$query = $this->CI->db->select('key,value')
->where('autoload', 'yes')
->get($this->table);
foreach ($query->result() as $row) {
$this->cache[$row->key] = $row->value;
$this->CI->config->set_item($row->key, $row->value);
}
$this->autoloaded = true;
return $this->cache;
}
// 讀取單項(優先級:緩存 → 數據庫 → CI config)
public function item($key) {
if (!$key) return false;
if (isset($this->cache[$key])) return $this->cache[$key];
$row = $this->CI->db->select('value')
->where('key', $key)
->get($this->table)
->row();
if ($row) {
$this->cache[$key] = $row->value;
return $row->value;
}
return $this->CI->config->item($key);
}
// 讀取整組配置
public function group($group) {
if (!$group) return false;
$query = $this->CI->db->select('key,value')
->where('group', $group)
->get($this->table);
$arr = [];
foreach ($query->result() as $row) {
$this->cache[$row->key] = $row->value;
$arr[$row->key] = $row->value;
}
return $arr ?: false;
}
// 更新配置
public function edit($key, $value) {
$this->CI->db->where('key', $key)
->update($this->table, ['value' => $value]);
if ($this->CI->db->affected_rows()) {
$this->cache[$key] = $value;
$this->CI->config->set_item($key, $value);
return true;
}
return false;
}
// 新增配置(存在則轉更新)
public function insert($key, $value = '', $group = 'addon', $autoload = 'no') {
if ($this->CI->db->where('key', $key)->get($this->table)->num_rows()) {
return $this->edit($key, $value);
}
$this->CI->db->insert($this->table, compact('key','value','group','autoload'));
if ($this->CI->db->affected_rows()) {
$this->cache[$key] = $value;
if ($autoload === 'yes') $this->CI->config->set_item($key, $value);
return true;
}
return false;
}
// 刪除單項
public function delete($key) {
$this->CI->db->delete($this->table, ['key' => $key]);
if ($this->CI->db->affected_rows()) {
unset($this->cache[$key]);
return true;
}
return false;
}
// 刪除整組
public function delete_group($group) {
$this->CI->db->delete($this->table, ['group' => $group]);
return (bool)$this->CI->db->affected_rows();
}
}
在 application/config/config.php 添加:
$config['settings_table'] = 'system_settings';
// 控制器中載入
$this->load->library('setting');
// 讀取自動加載項(同原生 config)
$siteName = $this->config->item('site_name');
// 讀取非自動加載項
$apiKey = $this->setting->item('api_secret');
// 讀取整組
$mailConf = $this->setting->group('mail');
// 寫入/更新
$this->setting->edit('site_name', '新站名');
$this->setting->insert('new_key', 'value', 'custom', 'yes');
// 刪除
$this->setting->delete('old_key');
$this->setting->delete_group('deprecated');
autoload() 寫入快取,item() 先查快取。edit/insert/delete 記錄操作者、舊值、新值、時間。value 存 JSON,讀取時自動 json_decode,支援陣列/對象配置。config/*.php 批量導入數據表,平滑遷移。這個 Setting 庫以最小代價為 CI 帶來了「動態配置中心」能力,適合中小型專案快速落地。大型系統建議改用 etcd/Consul/Apollo 等專業配置中心。