Issues

ZF-8636: Zend_Session with saveHandler db and Multi-Column Primary Key

Description

Hello, like explained there : http://framework.zend.com/manual/en/… and there http://framework.zend.com/manual/en/…

When I'm using the multi-column primary key I have a problem : {quote}
Fatal error: Uncaught exception 'Zend_Session_Exception' with message 'Zend_Session::start() - ..../library/Zend/Db/Table/Abstract.php(Line:900): Error #8 Undefined offset: 1 Array ..../library/Zend/Db/Table/Abstract.php(Line:900): Error #8 Undefined offset: 1 Array ..../library/Zend/Session/SaveHandler/DbTable.php(Line:528): Error #8 Undefined index: session_id Array ..../library/Zend/Session/SaveHandler/DbTable.php(Line:539): Error #8 Undefined index: session_id Array ..../library/Zend/Session/SaveHandler/DbTable.php(Line:528): Error #8 Undefined index: save_path Array ..../library/Zend/Session/SaveHandler/DbTable.php(Line:539): Err in ..../library/Zend/Session.php on line 493
{quote}

When I do the save with a PHP array of config, the problem doesn't exist. When I convert the ini config in an array with ->toArray(); I find some associative key that were not needed and make the session bugged. " To make this working I implements in the start of application (Zend_Application) this "anti-bug solution", it's uggly but it's a kind of solution while it will be fixed :


            if (isset($options['resources']['session']['saveHandler']['options']['primaryAssignment']))
            {
                $tmp = $options['resources']['session']['saveHandler']['options']['primary'];
                unset($options['resources']['session']['saveHandler']['options']['primary']);
                foreach ($tmp as $v)
                    $options['resources']['session']['saveHandler']['options']['primary'][] = $v;
    
                $tmp = $options['resources']['session']['saveHandler']['options']['primaryAssignment'];
                unset($options['resources']['session']['saveHandler']['options']['primaryAssignment']);
                foreach ($tmp as $v)
                    $options['resources']['session']['saveHandler']['options']['primaryAssignment'][] = $v;
            }

I take the database structure from the manual :


CREATE TABLE `session` (
    `session_id` char(32) NOT NULL,
    `save_path` varchar(32) NOT NULL,
    `name` varchar(32) NOT NULL DEFAULT '',
    `modified` int,
    `lifetime` int,
    `session_data` text,
    PRIMARY KEY (`Session_ID`, `save_path`, `name`)
);

And used an ini file to load all config :


resources.db.adapter = "Pdo_Mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = "root"
resources.db.params.dbname = "biblio"
resources.db.params.date_format = "YYYY-MM-ddTHH:mm:ss"
resources.db.isDefaultTableAdapter = true

resources.session.save_path = APPLICATION_PATH "/../data/session"
resources.session.use_only_cookies = true
resources.session.remember_me_seconds = 864000
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable"
resources.session.saveHandler.options.name = "session"
resources.session.saveHandler.options.primary.session_id = "session_id"
resources.session.saveHandler.options.primary.save_path = "save_path"
resources.session.saveHandler.options.primary.name = "name"
resources.session.saveHandler.options.primaryAssignment.sessionId = "sessionId"
resources.session.saveHandler.options.primaryAssignment.sessionSavePath = "sessionSavePath"
resources.session.saveHandler.options.primaryAssignment.sessionName = "sessionName"
resources.session.saveHandler.options.modifiedColumn = "modified"
resources.session.saveHandler.options.dataColumn = "session_data"
resources.session.saveHandler.options.lifetimeColumn = "lifetime"

When I'm boostrap I load db first :


    protected function _initDb()
    {
        //config
        $config = new Zend_Config($this->getOptions());
        //connexion
        try
        {
            $db = Zend_Db::factory($config->resources->db);
            $db->getConnection();
        }
        catch (Exception $e)
        {
            exit( $e->getMessage() );
        }

        // on save la connexion
        Zend_Registry::set( 'db', $db );
        Zend_Db_Table::setDefaultAdapter($db);

        return $db;
    }

    protected function _initSession()
    {
        $this->bootstrap('db');
        Zend_Session::start($this->getOptions());
        //...
    }

I used : * mysql 5.1.37 * php 5.2.10

If you need more information ask!

Comments

other temp solution resources.session.saveHandler.options.primary.0 = "session_id" resources.session.saveHandler.options.primary.1 = "save_path" resources.session.saveHandler.options.primary.2 = "name" resources.session.saveHandler.options.primaryAssignment.0 = "sessionId" resources.session.saveHandler.options.primaryAssignment.1 = "sessionSavePath" resources.session.saveHandler.options.primaryAssignment.2 = "sessionName"

@Nikolay Mogulev: Thanks, your solution seems to solve this. This is also present in ZF-1.10.1.

This is a problem in documentation Zend_Application_Resource_Session.

Exists several reported with the same problem ZF-6868, ZF-7000 and ZF-9599.

When using the obove fix, the following exception is being thrown:

Fatal error: Exception thrown without a stack frame in Unknown on line 0

Fixed with r23177

I find my error with this, my problem is the fields in the database aren't primary key, is need for this configuration, You need add to primary key session_id, save_path, name fields

Despite the message that this issue is resolved in version 1.11.0, I recently downloaded version 1.11.11 and I'm experiencing the same problem under the exact same circumstances.

The solution of Nikolay Mogulev works.

This is problem of documentation just check to see that this was been corrected ;). See http://framework.zend.com/manual/en/…