學習CodeIgniter大概有幾天了。從第一天瞭解後,對CI情有獨鍾,比較符合個人風格。其實一直以來對框架這塊不太敏感。本身長時間的開發,也有一套本身的開發風格和習慣。可是這年頭,你說你不會框架,你都很差意思說你是作開發的。因此就選擇一個框架來彌補這個缺點了。去年也接觸過thinkPHP,可是對於分組這塊,始終感受理解和掌握不到位,因爲時間關係,也就沒有深刻下去。此次也是由於在國慶節前有位客戶要求用框架開發。因此,也到了不起不掌握一門框架的地步了。因而國慶期間,在家偶爾看了一下官方文檔,甚是喜歡。這不,爲了一展身手,決定將之前的一個項目轉爲CI框架模式。一切順利,只是有一個問題讓我一時沒法解決,因而在「CI中國論壇」上求助,通過百度與GOOGLE的幫助,終於解決了這個心病,因而在此作個記錄,以作記念。php
在通常的開發模式中,網站都有一個全局配置,而正常狀況下,這些配置都保存在數據庫中的一個表中。個人項目是經過一個公共文件裏,從數據庫表中讀取配置信息,並存到緩存中(memcache),在須要的位置都包含這個文件,也就是說,只要第一次從數據庫讀取數據,那麼該數據就被緩存了,之後就能夠直接在緩存中取數據,而不須要每次讀數據庫。除非該緩存已清空(機器重啓的狀況下)。html
這個公共文件內容以下(爲了節約篇幅,代碼作了修改,只體現這個思路)mysql
$mem=new Memcache; $mem->connect("127.0.0.1",11211); $_config_arr=$mem->get('config'); //$_config_arr=''; if(!is_array($_config_arr)){ //從數據庫讀取配置文件 $query=mysql_query('select webname,domain,default_lang from config where id=1'); if(mysql_num_rows($query)){ $arr=mysql_fetch_array($query); $mem->set('config',$arr,0,0); $_config_arr=$mem->get('config'); } } if(is_array($_config_arr)){ $_webname=$_config_arr[webname]; $_domain=$_config_arr[domain]; $_default_lang=$_config_arr[default_lang]; }
可能想到的有幾個辦法,但這些辦法要麼行不通,要麼太繁瑣。web
一、在入口文件index.php中實現。後瞭解,在此文件中實現沒法加載數據庫。總不能單獨寫個鏈接數據庫這樣的東西吧,就跟一坨屎同樣。sql
二、在helper中寫,helper其實就是 include,可是helper仍然在數據庫加載以前就已加載。數據庫
三、寫一個模型中,而後自動加載該模型,並在模型中將數據寫到緩存中?windows
四、瘋狂百度GOOGLE中....緩存
在「CI中國論壇」瞭解到,CI只支持memcached,而不支持memcache,而memcached是在unix中的,windows系統上只有memcache。而遺憾的是,我用的就是windows,猶如晴天霹靂。我想,若是CI不支持,也只有經過$mem=new Memcache;這樣的方式寫了。就是感受彆扭。幸虧,找到了解決辦法。具體訪問:服務器
CI system/libraries/Cache/drivers/memcached.php 兼容 memcache,memcached擴展app
解決了CI不支持memcache的問題。解決方案:將上面連接中的代碼整理好覆蓋原文件內容。(爲何要整理?若是直接複製,因爲網頁緣由,有一段本是註釋程序卻未被註釋,將會致使出錯。本篇末尾提供memcached.php代碼,你也能夠直接拷貝並替換原文件。)
五、發貼尋求幫助,在嘗試測試下終於理順思路,解決如本篇文章標題所示的問題。在此提供解決方案,歡迎交流,若是有更好方案,也但願與我分享。感謝。
網友提供幫助內容以下:
經過擴展CI_Controller類,增長一個或多個方法,這樣在全部的控制器均可以使用這些方法了,就像公用方法了。在這些方法中對數據庫進行操做。 例如 MY_Controller類繼承於CI_Controller,你的控制器繼承於MY_Controller。在MY_Controller中增長個options方法,這個方法對數據庫進行操做,之後在每一個控制器的方法中均可以使用options()方法獲取你須要的信息了。 (擴展核心類)請看手冊,恕我沒法一一細說:http://codeigniter.org.cn/user_guide/general/core_classes.html
MY_Controller代碼以下:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class MY_Controller extends CI_Controller{ public function __construct(){ parent::__construct(); $this->load->driver('cache'); $this->load->model('manager_model'); $_config_arr=$this->cache->memcached->get('config'); if(!is_object($_config_arr)){ $_config_arr=$this->manager_model->get_config(); $this->cache->memcached->save('config',$_config_arr,0); } if(is_object($_config_arr)){ $data['_webname']=$_config_arr->webname; $data['_domain']=$_config_arr->domain; $data['_default_lang']=$_config_arr->default_lang; $this->load->vars($data); } } }manager_model模型中get_config()方法代碼以下:
function get_config(){ $query = $this->db->query('select id,webname,domain,default_lang from config where id=1'); if($query->num_rows()) { return $query->row(); } }控制器中加載config.php視圖方法以下:
public function config(){ $this->load->view('public/config');//這裏無需傳遞第二個參數。 }config方法中,若是有其它參數,也以經過第二個參數傳遞。不影響傳遞$data的值。好比:
public function config(){ $data1['title']='這是標題'; $data1['keyword']='這是關鍵字'; $this->load->view('public/config',$data1); }在視圖public/config.php文件中,便可以使用$data中全部變量,也可使用$title和$keyword變量。
Memcached 緩存 使用分佈式 Memcached 服務器 能夠經過配置文件: memcached.php 來配置,該文件在 application/config/ 目錄下. All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows: $this->load->driver('cache'); $this->cache->memcached->save('foo', 'bar', 10); 若想了解更多關於 Memcached的信息, 請參考 http://php.net/memcached來源:http://codeigniter.org.cn/user_guide/drivers/caching.html#dummy
個人CodeIgniter 版本 2.1.2,卻在application/config中找不到memcached.php這個配置文件
其實,須要手工在該目錄建立,內容默認以下:
$config['memcached'] = array( 'hostname' => '127.0.0.1', 'port' => 11211, 'weight' => 1 );
說明:上面的「Cache_memcached.php」中已經有默認的值,該值與上面這個配置文件內容相同。若是你的設置與默認值剛好相同,也能夠不用創建memcached.php這個配置文件。若是不一樣,你也能夠直接更改 Cache_memcached.php 文件中的配置值。可是,你一旦創建memcached.php這個配置文件,那麼該值將會覆蓋 Cache_memcached.php 中的默認值。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CodeIgniter * * An open source application development framework for PHP 4.3.2 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 2.0 * @filesource */ // ------------------------------------------------------------------------ /** * CodeIgniter Memcached Caching Class * * @package CodeIgniter * @subpackage Libraries * @category Core * @author ExpressionEngine Dev Team * @link */ class CI_Cache_memcached extends CI_Driver { private $_memcached; // Holds the memcached object protected $_memcache_conf = array( 'default' => array( 'default_host' => '127.0.0.1', 'default_port' => 11211, 'default_weight' => 1 ) ); // ------------------------------------------------------------------------ /** * Fetch from cache * * @param mixed unique key id * @return mixed data on success/false on failure */ public function get($id) { $data = $this->_memcached->get($id); return (is_array($data)) ? $data[0] : FALSE; } // ------------------------------------------------------------------------ /** * Save * * @param string unique identifier * @param mixed data being cached * @param int time to live * @return boolean true on success, false on failure */ public function save($id, $data, $ttl = 60) { if (get_class($this->_memcached) == 'Memcached') { return $this->_memcached->set($id, array($data, time(), $ttl), $ttl); } else if (get_class($this->_memcached) == 'Memcache') { return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl); } return FALSE; } // ------------------------------------------------------------------------ /** * Delete from Cache * * @param mixed key to be deleted. * @return boolean true on success, false on failure */ public function delete($id) { return $this->_memcached->delete($id); } // ------------------------------------------------------------------------ /** * Clean the Cache * * @return boolean false on failure/true on success */ public function clean() { return $this->_memcached->flush(); } // ------------------------------------------------------------------------ /** * Cache Info * * @param null type not supported in memcached * @return mixed array on success, false on failure */ public function cache_info($type = NULL) { return $this->_memcached->getStats(); } // ------------------------------------------------------------------------ /** * Get Cache Metadata * * @param mixed key to get cache metadata on * @return mixed FALSE on failure, array on success. */ public function get_metadata($id) { $stored = $this->_memcached->get($id); if (count($stored) !== 3) { return FALSE; } list($data, $time, $ttl) = $stored; return array( 'expire' => $time + $ttl, 'mtime' => $time, 'data' => $data ); } // ------------------------------------------------------------------------ /** * Setup memcached. */ private function _setup_memcached() { // Try to load memcached server info from the config file. $CI =& get_instance(); if ($CI->config->load('memcached', TRUE, TRUE)) { if (is_array($CI->config->config['memcached'])) { $this->_memcache_conf = NULL; foreach ($CI->config->config['memcached'] as $name => $conf) { $this->_memcache_conf[$name] = $conf; } } } if (extension_loaded('memcached')){ $this->_memcached = new Memcached(); }else{ $this->_memcached = new Memcache(); } foreach ($this->_memcache_conf as $name => $cache_server) { if ( ! array_key_exists('hostname', $cache_server)) { // $cache_server['hostname'] = $this->_default_options['default_host']; //坑爹的原代碼,沒有_default_options屬性 $cache_server['hostname'] = $this->_memcache_conf['default']['default_host']; } if ( ! array_key_exists('port', $cache_server)) { // $cache_server['port'] = $this->_default_options['default_port'];//坑爹的原代碼,沒有_default_options屬性 $cache_server['port'] = $this->_memcache_conf['default']['default_port']; } if ( ! array_key_exists('weight', $cache_server)) { // $cache_server['weight'] = $this->_default_options['default_weight'];//坑爹的原代碼,沒有_default_options屬性 $cache_server['weight'] = $this->_memcache_conf['default']['default_weight']; } //致使若是不配置 config/memcache.php文件,執行到$this->_memcached->addServer($cache_server['hostname'],$cache_server['port']);出錯(由於此時語句,至關於$this->_memcached->addServer(‘’,'');而後機器木反應了~ if (extension_loaded('memcached')){ $this->_memcached->addServer( $cache_server['hostname'], $cache_server['port'], $cache_server['weight'] ); }else{ $this->_memcached->addServer($cache_server['hostname'],$cache_server['port'],TRUE, $cache_server['weight']); } } } // ------------------------------------------------------------------------ /** * Is supported * * Returns FALSE if memcached is not supported on the system. * If it is, we setup the memcached object & return TRUE */ public function is_supported() { if ( !extension_loaded('memcached') && !extension_loaded('memcache')) { log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.'); return FALSE; } $this->_setup_memcached(); return TRUE; } // ------------------------------------------------------------------------ } // End Class /* End of file Cache_memcached.php */ /* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
http://www.php.net/manual/zh/memcached.addserver.php
http://www.php.net/manual/zh/memcache.addserver.php
一、_setup_memcached()方法修改
原內容:(由於只考慮了memcached)
$this->_memcached = new Memcached();修改成:
if (extension_loaded('memcached')){ $this->_memcached = new Memcached(); }else{ $this->_memcached = new Memcache(); }二、原類中沒有_default_options屬性
因爲沒有_default_options屬性,因此致使_setup_memcached()方法中全部關於此句的代碼都要換個方式。也能夠創建個_default_options屬性。上面代碼中是將
$cache_server['hostname'] = $this->_default_options['default_host'];更改成
$cache_server['hostname'] = $this->_memcache_conf['default']['default_host'];還包括port 和 weight的取值。
三、is_supported() 方法
將原內容:
if ( ! extension_loaded('memcached'))修改成:
if ( !extension_loaded('memcached') && !extension_loaded('memcache'))這些改動內容都不用多作解釋。在這只是將改動部分與原內容作一個說明。