Search code examples
phpzend-frameworksessioncache-control

Zend - How to enable cache(MetaData) on session table?


i am using Zend_Session_SaveHandler_DbTable to store the session in a table

my profiler tells me that on each page request zend does:

# Query Time

(1) connect 0.0032038688659668

(2) DESCRIBE session 0.0041539669036865

(3) SELECT session.* FROM session WHERE (((session.session_id = '7nnan8ltd6h64sigs6dlkicvh0' AND session.save_path = '' AND session.name = 'PHPSESSID'))) 0.00057697296142578

Total time : 0.008 sec

when i do queries on other tables, zend DESCRIBEs them once(the first time it access that table), then if i refresh the page it only does the query with no Describe, on the session table it does DESCRIBE on every page (since i use authentication ... )

how can i cache only the metadata on the session table?

i am currently using this

class Gestionale_Application_Resource_Cache extends Zend_Application_Resource_ResourceAbstract{
public function init ()
{
    $options = $this->getOptions();

    // Get a Zend_Cache_Core object

    //valori che vengono presi dal file di configurazione
    $cache = Zend_Cache::factory(
        $options['frontEnd'],
        $options['backEnd'],
        $options['frontEndOptions'],
        $options['backEndOptions']);
    Zend_Registry::set('cache', $cache);

    Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);//per mettere in cache la meta-info
    return $cache;
}

this is my config file

...
;cache stuff
resources.cache.frontEnd = core 
resources.cache.backEnd = file 
resources.cache.frontEndOptions.lifetime = 1200 ; in secondi
resources.cache.frontEndOptions.automatic_serialization = true 
resources.cache.backEndOptions.lifetime = 3600 ; in secondi
resources.cache.backEndOptions.cache_dir = APPLICATION_PATH "/../cache"
pluginPaths.Gestionale_Application_Resource = APPLICATION_PATH "/../library/Gestionale/Application/Resource"  
;;fine cache stuff

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.db.params.charset = "utf8"
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "gestionale"
resources.db.isDefaultTableAdapter = true
autoloaderNamespaces[] = "Gestionale_";serve per caricare il plugin di sotto quando si usa anche ZFdebug
resources.frontController.plugins.acl = "Gestionale_Controller_Plugin_Acl"
resources.db.params.profiler = true
...

this is my session table

CREATE TABLE IF NOT EXISTS `session` (
  `session_id` char(32) NOT NULL,
  `save_path` varchar(32) NOT NULL,
  `name` varchar(32) NOT NULL DEFAULT '',
  `modified` int(11) DEFAULT NULL,
  `lifetime` int(11) DEFAULT NULL,
  `session_data` text,
  PRIMARY KEY (`session_id`,`save_path`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

thanks :D


Solution

  • Wherever you are initializing the session save handler, either in the bootstrap or the config file, make sure that you call Zend_Db_Table_Abstract::setDefaultMetadataCache() first.

    To specify it in your config file, put the session config after the ;;fine cache stuff line:

    ...
    ;cache stuff
    resources.cache.frontEnd = core 
    resources.cache.backEnd = file 
    resources.cache.frontEndOptions.lifetime = 1200 ; in secondi
    resources.cache.frontEndOptions.automatic_serialization = true 
    resources.cache.backEndOptions.lifetime = 3600 ; in secondi
    resources.cache.backEndOptions.cache_dir = APPLICATION_PATH "/../cache"
    pluginPaths.Gestionale_Application_Resource = APPLICATION_PATH "/../library/Gestionale/Application/Resource"  
    ;;fine cache stuff
    
    resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable"
    resources.session.saveHandler.options.name = "session"
    resources.session.saveHandler.options.primary[] = "session_id"
    resources.session.saveHandler.options.primary[] = "save_path"
    resources.session.saveHandler.options.primary[] = "name"
    resources.session.saveHandler.options.primaryAssignment[] = "sessionId"
    resources.session.saveHandler.options.primaryAssignment[] = "sessionSavePath"
    resources.session.saveHandler.options.primaryAssignment[] = "sessionName"
    resources.session.saveHandler.options.modifiedColumn = "modified"
    resources.session.saveHandler.options.dataColumn = "session_data"
    resources.session.saveHandler.options.lifetimeColumn = "lifetime"
    
    resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
    resources.db.params.charset = "utf8"
    ...
    

    Or, if you don't want to rely on their order in the config file, you can add an _initSession() method to your bootstrap class that specifically loads them in the correct order:

    protected function _initSession()
    {
        $this->bootstrap('cache');
        $this->bootstrap('session');
    }