facebook twitter hatena line google mixi email

Php/zend framework/DBモデルをキャッシュ化

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
  • /application/configs/cache.ini
[production]
; キャッシュサーバ設定
memcached.servers.0.host = localhost
memcached.servers.0.port = 11211
memcached.servers.0.weight = 100
; 全体キャッシュ有効期限秒
memcached.lifetime = 7200
; 全体キャッシュ使用有無
memcached.cache.use = TRUE
; 全体キャッシュ名頭文字
memcached.cache.idPrefix = MEM1_
; DBキャッシュ有効期限秒
memcached.db.lifetime = 7200
; DBキャッシュ使用有無(全体キャッシュ使用有無がTRUEのとき有効
memcached.db.cache.use = TRUE
; DBキャッシュ名頭文字(全体キャッシュ依存
memcached.db.cache.idPrefix = DB_

[staging : production]

[testing : production]

[development : production]
  • /application/models/MemcachedModel.php
<?php
/**
 * memcachedモデルクラス
 */
class MemcachedModel
{
    // キャッシュインスタンス
    private $_cache = NULL;
    // キャッシュ使用フラグ
    private $_cacheUse = TRUE;
    // キャッシュIDプレフィックス
    private $_cacheIdPrefix = NULL;
    /**
     * constructor
     */
    public function __construct()
    {
        // 外部iniをロードしZend_Configオブジェクトを生成
        $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/cache.ini', APPLICATION_ENV);
        // キャッシュ使用フラグ
        $this->_cacheUse = $config->memcached->cache->use;
        // キャッシュプレフィックスID
        $this->_cacheIdPrefix = $config->memcached->cache->idPrefix;
        
        // FrontEnd に関する設定
        $frontendOptions = array(
            'lifetime' => $config->memcached->lifetime, //7200, // キャッシュの有効期限を 2 時間とする
            'automatic_serialization' => TRUE,
            'cache_id_prefix' => $this->_cacheIdPrefix
        );
        // BackEndに関する設定
        $backendOptions = array(
            'servers' => array( // memcached の設定にあわせる
                         array(
                             'host'       => $config->memcached->servers->{0}->host, //'localhost',
                             'port'       => $config->memcached->servers->{0}->port, //11211,
                             'persistent' => TRUE
                         )
                     )
        );
        // キャッシュオブジェクトを生成
        $this->_cache      = Zend_Cache::factory('Output', 'Memcached', $frontendOptions, $backendOptions);
    }
    /**
     * キャッシュ設定
     */
    public function setCache($key, $value, $tags = array(), $specificLifetime = false)
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        $result = $this->_cache->save($value, $key, $tags, $specificLifetime);
        if (!$result) {
            // cache error
        }
        return $result;
    }
    /**
     * キャッシュ取得
     */
    public function getCache($key)
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        if (($result = $this->_cache->load($key))) {
            return $result;
        }
    }
    /**
     * キャッシュ削除
     */
    public function delCache($key)
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        $this->_cache->remove($key);
    }
    /**
     * キャッシュ全削除
     */
    public function cleanCache($tags = array())
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        $this->_cache->clean(Zend_Cache::CLEANING_MODE_ALL, $tags);
    }
}
  • /application/models/dao/AbstractDao.php
<?php
require_once APPLICATION_PATH . '/models/MemcachedModel.php';
require_once APPLICATION_PATH . '/models/ConfigModel.php';
/**
 * 基底Daoクラス
 */
abstract class AbstractDao extends Zend_Db_Table_Abstract
{
    // キャッシュインスタンス
    private $_cache = NULL;
    // キャッシュ使用フラグ
    private $_cacheUse = TRUE;
    // キャッシュIDプレフィックス
    private $_cacheIdPrefix = NULL;
    /**
     * キャッシュコネクション
     */
    public function createCacheConnection()
    {
        // 外部iniをロードしたZend_Configオブジェクトを取得(毎回取得すると重いのでシングルトンで取得
        $config = ConfigModel::getInstance(APPLICATION_PATH . '/configs/cache.ini', APPLICATION_ENV);
        // キャッシュ使用フラグ
        $this->_cacheUse = $config->memcached->db->cache->use;
        // キャッシュ未使用時
        if ($this->_cacheUse == FALSE) {
            return FALSE;
        }
        // キャッシュオブジェクトを生成
        $this->_cache = new MemcachedModel();
        // キャッシュID
        $this->_cacheIdPrefix = sprintf("DB_%s_%s_", $this->_schema, $this->_name);
    }
    /**
     * キャッシュ設定
     */
    public function setCache($key, $value)
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        $this->_cache->setCache($this->_cacheIdPrefix . $key, $value, array($this->_cacheIdPrefix));
    }
    /**
     * キャッシュ取得
     */
    public function getCache($key)
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        return $this->_cache->getCache($this->_cacheIdPrefix . $key);
    }
    /**
     * キャッシュ削除
     */
    public function delCache($key)
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        return $this->_cache->delCache($this->_cacheIdPrefix . $key);
    }
    /**
     * キャッシュ削除(by プレフィックス指定
     */
    public function cleanCache()
    {
        if ($this->_cacheUse == FALSE) return FALSE;
        return $this->_cache->cleanCache(array($this->_cacheIdPrefix));
    }
}
  • /application/models/dao/SamplesDao.php
require_once dirname(__FILE__) . '/AbstractDao.php';
// サンプルDao
class SamplesDao extends AbstractDao
{
  public function fetchRowById($id)
  {
    // キャッシュコネクション生成
    $this->createCacheConnection();
    // キャッシュ取得
    $cache = $this->getCache($id);
    if ($cache) {
      return $cache;
    }
    // 処理
    $where = $this->getAdapter()->quoteInto('id = ?', $id);
    $sample = $this->fetchRow($where);
    // キャッシュ設定
    $this->setCache($id, $sample);
  }
  public function updateById($id)
  {
    // 処理
    $where = $this->getAdapter()->quoteInto('id = ?', $id);
    $id = parent::update($data, $where);
    // キャッシュコネクション生成
    $this->createCacheConnection();
    // キャッシュ削除
    $this->delCache($id);
    return $id;
  }
}
  • /application/models/ConfigModel.php
/**
 * ConfigModel(シングルトン
 *
 * @ex
 * Zend_Config_IniをgetInstance()を用いて取得する
 * $config = ConfigModel::getInstance($path, $env);
 *
 * 毎回同じiniを読み込むと重いので、このクラス内にインスタンスを保存
 * Zend_Config_Iniを継承するとエラーとなったので、プロパティにZend_Config_Iniをそのまま入れた
 */
class ConfigModel
{
    private static $singleton = array();
    private function __construct()
    {
    }
    public static function getInstance($path, $env = NULL) {
        // クラス内保存用プロパティ名(ユニーク名)取得
        $name = md5($path . $env);
        // list($name, $dammy) = explode('.', basename($path));
        if (!array_key_exists($name, self::$singleton)) {
            // Zendコンフィグインスタンス取得
            self::$singleton[$name] = new Zend_Config_Ini($path, $env);
        }
        return self::$singleton[$name];
    }
}