I am busy writing a DB Session module so I can quickly install it between multiple applications. The module will be loaded from the autoloader as the first module to be started. What I'm trying to accomplish is to change the default session container / session handler to be the default session handler for all modules and it should also be database hosted sessions. I've been strugling with zf2 session handler for quite a while now and the errors in the logs make 0 sense. So here what I have so far. A basic module with Module.php containing...
namespace DBSession;
use Zend\Mvc\ModuleRouteListener;
class Module {
public function onBootstrap($e) {
$e->getApplication()->getServiceManager()->get('translator');
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$config = $e->getApplication()->getServiceManager()->get('Config');
$controller = $e->getTarget();
$controller->config = $config;
new \DBSession\Storage\DBStorage();
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
And the actual class that initiates the DB session handler.
namespace DBSession\Storage;
use Zend\Session\SaveHandler\DbTableGateway;
use Zend\Session\SaveHandler\DbTableGatewayOptions;
use Zend\Db\Adapter\Adapter;
use Zend\Session\SessionManager;
use Zend\Session\Container;
class DBStorage {
public function __construct() {
$dbAdapter = new Adapter(array(
'driver' => 'Mysqli',
'host' => 'localhost',
'dbname' => 'zf2_session',
'username' => 'zf2',
'password' => 'testme',
'options' => array(
'buffer_results' => true,
),
));
$tableGateway = new \Zend\Db\TableGateway\TableGateway('session', $dbAdapter);
$gwOpts = new DbTableGatewayOptions();
$gwOpts->setDataColumn('data');
$gwOpts->setIdColumn('id');
$gwOpts->setLifetimeColumn('lifetime');
$gwOpts->setModifiedColumn('modified');
$gwOpts->setNameColumn('name');
$saveHandler = new DbTableGateway($tableGateway, $gwOpts);
$sessionManager = new SessionManager();
$sessionManager->setSaveHandler($saveHandler);
return Container::setDefaultManager($sessionManager);
}
}
When trying to create a session I see the following in the logs which I have 0 clue how to fix. This is starting to make me hate magic...
[29-Nov-2012 20:47:28 UTC] PHP Fatal error: Uncaught exception 'Zend\Db\Sql\Exception\InvalidArgumentException' with message 'Not a valid magic property for this object' in /document_root/vendor/zendframework/zendframework/library/Zend/Db/Sql/Select.php:764
Stack trace:
#0 /document_root/vendor/zendframework/zendframework/library/Zend/Db/Sql/Select.php(163): Zend\Db\Sql\Select->__get('tableReadOnly')
#1 /document_root/vendor/zendframework/zendframework/library/Zend/Db/Sql/Select.php(146): Zend\Db\Sql\Select->from('session')
#2 /document_root/vendor/zendframework/zendframework/library/Zend/Db/Sql/Sql.php(65): Zend\Db\Sql\Select->__construct('session')
#3 /document_root/vendor/zendframework/zendframework/library/Zend/Db/TableGateway/AbstractTableGateway.php(191): Zend\Db\Sql\Sql->select()
#4 /document_root/vendor/zendframework/zendframework/library/Zend/Session/SaveHandler/DbTableGateway.php(134): Zend\Db\TableGateway\AbstractTableGateway->select(Array)
#5 [internal function]: Zend\Session\SaveHandler\DbTableGateway->write(' in /document_root/vendor/zendframework/zendframework/library/Zend/Db/Sql/Select.php on line 764
After all of the fixes that have recently gone into ZF2 my original solution is now working without modification however, I have added a new composer module for anyone that wants to use it, it reduces the need to do it all manually.
Installation details are in the readme file on: https://github.com/Nitecon/DBSessionStorage
Enjoy and let me know if you have any issues.