我正忙于编写一个DB会话模块,以便可以在多个应用程序之间快速安装它。该模块将作为要启动的第一个模块从自动加载器加载。我试图完成的是将默认会话容器/会话处理程序更改为所有模块的默认会话处理程序,并且它也应该是数据库托管的会话。我已经使用zf2会话处理程序很长一段时间了,日志中的错误没有任何意义。这就是我到目前为止所得到的。一个带有Module.php的基本模块,包含...
命名空间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__,
),
),
);
}
}以及启动DB会话处理程序的实际类。
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);
}
}当尝试创建会话时,我在日志中看到以下内容,我不知道如何修复这些内容。这让我开始讨厌魔法了。
[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发布于 2013-03-30 01:48:02
在完成了ZF2的所有修复之后,我原来的解决方案现在无需修改就可以工作了,但是,我已经为任何想要使用它的人添加了一个新的composer模块,它减少了手动完成所有这些工作的需要。
安装详细信息位于以下位置的自述文件中:https://github.com/Nitecon/DBSessionStorage
请尽情享受,如果你有任何问题,请告诉我。
发布于 2012-11-30 17:59:44
更新:
zend框架>= 2.2,这个问题已经不存在了。
的老答案:
我在将会话存储到数据库时也遇到过同样的问题,我在基本模块类\module\Application\Module.php中编写了initDbSession函数
class Module
{
public function onBootstrap(MvcEvent $e)
{
$e->getApplication()->getServiceManager()->get('translator');
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
// session start from here
$this->initDbSession( $e );
}
/**
* Store session into database
*
* @param type $e
*/
private function initDbSession( MvcEvent $e )
{
// grab the config array
$serviceManager = $e->getApplication()->getServiceManager();
$config = $serviceManager->get('config');
$dbAdapter = $serviceManager->get('Zend\Db\Adapter\Adapter');
/* some how this not works for me
$sessionOptions = new \Zend\Session\SaveHandler\DbTableGatewayOptions( null );
$sessionTableGateway = new \Zend\Db\TableGateway\TableGateway('session', $dbAdapter);
$saveHandler = new \Zend\Session\SaveHandler\DbTableGateway($sessionTableGateway, $sessionOptions);
*/
/* I written my own save handler , I am using mysql as database */
$saveHandler = new \My\Session\SaveHandler\Mysql( $config['db'] );
$sessionConfig = new \Zend\Session\Config\SessionConfig();
$sessionConfig->setOptions($config['session']);
// pass the saveHandler to the sessionManager and start the session
$sessionManager = new \Zend\Session\SessionManager( $sessionConfig , NULL, $saveHandler );
$sessionManager->start();
\Zend\Session\Container::setDefaultManager($sessionManager);
}
// other function goes here ...下面是我的配置文件,它位于\config\autoload\global.php中
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
'buffer_results' => true
),
'username' => 'root',
'password' => '',
'host' => 'localhost',
'dbname' => 'zf2',
),
'session' => array(
'remember_me_seconds' => 2419200,
'use_cookies' => true,
'cookie_httponly' => true,
'cookie_lifetime' => 2419200,
'gc_maxlifetime' => 2419200,
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory'
)
)
);Mysql表结构为
CREATE TABLE `session` (
`id` CHAR(32) NOT NULL DEFAULT '',
`name` VARCHAR(255) NOT NULL,
`modified` INT(11) NULL DEFAULT NULL,
`lifetime` INT(11) NULL DEFAULT NULL,
`data` TEXT NULL,
PRIMARY KEY (`id`)
)COLLATE='utf8_general_ci' ENGINE=InnoDB;下面给出了自定义Mysql保存处理程序类。我之所以写这个类,是因为新的Zend\Session\SaveHandler\DbTableGateway不能在我的服务器上工作。我在\library\My\Session\SaveHandler\Mysql.php上编写的自定义Mysql会话保存处理程序类
<?php
namespace My\Session\SaveHandler;
use Zend\Session\SaveHandler\SaveHandlerInterface;
/**
* Description of Mysql
*
* @author rab
*/
class Mysql implements SaveHandlerInterface
{
/**
* Session Save Path
*
* @var string
*/
protected $sessionSavePath;
/**
* Session Name
*
* @var string
*/
protected $sessionName;
/**
* Lifetime
* @var int
*/
protected $lifetime;
/**
* Constructor
*
*/
public function __construct( $dbConfig )
{
$this->dbconn = mysql_connect(
$dbConfig['host'],
$dbConfig['username'],
$dbConfig['password']
);
if ( $this->dbconn ) {
return mysql_select_db($dbConfig['dbname'], $this->dbconn);
}
}
/**
* Open the session
*
* @return bool
*/
public function open( $savePath, $name )
{
$this->sessionSavePath = $savePath;
$this->sessionName = $name;
$this->lifetime = ini_get('session.gc_maxlifetime');
return true;
}
/**
* Close the session
*
* @return bool
*/
public function close()
{
return mysql_close($this->dbconn);
}
/**
* Read the session
*
* @param int session id
* @return string string of the sessoin
*/
public function read($id)
{
$id = mysql_real_escape_string($id);
$sql = "SELECT `data` FROM `session` " .
"WHERE id = '$id'";
if ( $result = mysql_query($sql, $this->dbconn)) {
if ( mysql_num_rows($result) ) {
$record = mysql_fetch_assoc($result);
return $record['data'];
}
}
return '';
}
/**
* Write the session
*
* @param int session id
* @param string data of the session
*/
public function write($id, $data )
{
$data = (string) $data ;
$dbdata = array(
'modified' => time(),
'data' => mysql_real_escape_string( $data ) ,
);
$selectSql = "SELECT * FROM session
WHERE id = '$id' AND name = '{$this->sessionName}' ";
$rs = mysql_query( $selectSql, $this->dbconn );
if ( $rs = mysql_query( $selectSql , $this->dbconn)) {
if ( mysql_num_rows($rs) ) {
$updateSql = "UPDATE `session` SET
`modified`= '".$dbdata['modified'] . "' ,
`data`= '".$dbdata['data']. "'
WHERE id= '$id' AND name = '{$this->sessionName}' ";
mysql_query( $updateSql , $this->dbconn );
return true;
}
}
$dbdata['lifetime'] = $this->lifetime;
$dbdata['id'] = $id;
$dbdata['name'] = $this->sessionName;
$insertSql = "INSERT INTO session (". implode(',' , array_keys($dbdata)) .")"
."VALUES ('" . implode("','" , array_values( $dbdata )). "')";
return mysql_query( $insertSql, $this->dbconn);
}
/**
* Destoroy the session
*
* @param int session id
* @return bool
*/
public function destroy($id)
{
$sql = sprintf("DELETE FROM `session` WHERE `id` = '%s'", $id);
return mysql_query($sql, $this->dbconn);
}
/**
* Garbage Collector
*
* @param int life time (sec.)
* @return bool
*/
public function gc( $maxlifetime )
{
$sql = sprintf("DELETE FROM `session` WHERE `modified` < '%s'",
mysql_real_escape_string(time() - $maxlifetime)
);
return mysql_query($sql, $this->dbconn);
}
}它将我的会话值保存到db表中。有关更多信息,请查看http://php.net/manual/en/function.session-set-save-handler.php
发布于 2013-03-13 03:38:19
这里有另一个类似的解决方案:How to use cookie in Zend Framework 2?
请确保更改此行:
Session::setDefaultManager($sessionManager);使用这一条:
Container::setDefaultManager($sessionManager);使用:
use Zend\Session\Container;https://stackoverflow.com/questions/13634490
复制相似问题