Как реализовать сеансы в базе данных при использовании ZF3 и Doctrine?
Руководство говорит:
Могут быть случаи, когда вы хотите создать обработчик сохранения, который в настоящее время не существует. Создание пользовательского обработчика сохранения очень похоже на создание пользовательского обработчика сохранения PHP. Все обработчики сохранения должны реализовывать Zend\Session\SaveHandler\SaveHandlerInterface. Как правило, если у вашего обработчика сохранения есть параметры, вы создадите другой класс параметров для конфигурации обработчика сохранения.
Я попытался создать собственный класс, реализующий этот интерфейс, но получаю следующую ошибку:
expects a class implementing Zend\Session\Storage\StorageInterface'
с этим конфигом:
'session_storage' => [
// 'type' => SessionArrayStorage::class (with array storage works ok)
'type' => \Application\Session\SaveHandler\Doctrine::class (tried to implement suggested interface)
],
Обратите внимание, что в руководстве предлагается SaveHandlerInterface
, но ожидается StorageInterface
.
Любой пример, как это сделать?
Изменить:
Моя текущая реализация.
In global.php
:
'session_config' => [
// Session cookie will expire in 1 hour.
'cookie_lifetime' => 60*60*1,
// Session data will be stored on server maximum for 30 days.
'gc_maxlifetime' => 60*60*24*30,
],
// Session manager configuration.
'session_manager' => [
// Session validators (used for security).
'validators' => [
RemoteAddr::class,
HttpUserAgent::class,
]
],
// Session storage configuration.
'session_storage' => [
'type' => \Application\Session\Storage\Doctrine::class,
],
'session_containers' => [
'UserSession'
]
in Module.php
:
/**
* This method is called once the MVC bootstrapping is complete.
*/
public function onBootstrap(MvcEvent $event)
{
$application = $event->getApplication();
$serviceManager = $application->getServiceManager();
// The following line instantiates the SessionManager and automatically
// makes the SessionManager the 'default' one
/** @var SessionManager $sessionManager */
$sessionManager = $serviceManager->get(SessionManager::class);
$entityManager = $serviceManager->get('doctrine.entitymanager.orm_default');
/** @var Doctrine $storage */
$storage = $sessionManager->getStorage();
$storage->setEntityManager($
}
in Application\Session\Storage\Doctrine.php
:
class Doctrine implements
IteratorAggregate,
StorageInterface,
StorageInitializationInterface
{
public function setEntityManager($em) {
$this->entityManager = $em;
}
// ...
// other functions as required by interfaces
}
Это работает, но недостаток в том, что Doctrine Storage будет доступен только в этом модуле, и я специально ввожу его при каждом запросе (Boostrap), а не тогда, когда это действительно нужно (Factory).
**Обновлять: **
Я написал SaveHandler
, но похоже значения не сохраняются после запросов.
Вот код:
class Doctrine extends ArrayStorage implements SaveHandlerInterface {
/**
* @param string $session_id
* @return string Encdoded session data string
*/
public function read($session_id)
{
$entity = $this->getEntity($session_id);
if ($entity) {
return $entity->getSessionData();
// sample output:
// string '__ZF|a:2:{s:20:"_REQUEST_ACCESS_TIME";d:1501933765.497678;s:6:"_VALID";a:3:{s:25:"Zend\Session\Validator\Id";s:26:"3kr15rhi6ijhneu7rruro9gr76";s:33:"Zend\Session\Validator\RemoteAddr";s:9:"127.0.0.1";s:36:"Zend\Session\Validator\HttpUserAgent";s:133:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36";}}FlashMessenger|C:23:"Zend\Stdlib\ArrayObject":205:{a:4:{s:7:"storage";a:0:{}s:4:"flag";i:2;s:13:"iteratorClass";s:13:"ArrayI'... (length=645)
// note that counter is not present
}
}
/**
* @param string $session_id
* @param string $session_data Encoded session data string
* @return bool
*/
public function write($session_id, $session_data)
{
// sample input ($session_data):
// string '__ZF|a:2:{s:20:"_REQUEST_ACCESS_TIME";d:1501934933.9573331;s:6:"_VALID";a:3:{s:25:"Zend\Session\Validator\Id";s:26:"3kr15rhi6ijhneu7rruro9gr76";s:33:"Zend\Session\Validator\RemoteAddr";s:9:"127.0.0.1";s:36:"Zend\Session\Validator\HttpUserAgent";s:133:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36";}}UserSession|C:23:"Zend\Stdlib\ArrayObject":223:{a:4:{s:7:"storage";a:1:{s:7:"counter";i:1;}s:4:"flag";i:2;s:13:"iteratorCla'... (length=918)
// (note that counter variable is set)
$entity = $this->getEntity($session_id);
$entity->setSessionData($session_data);
$entity->setLifetime($this->getLifeTime());
$this->getEntityManager()->persist($entity);
$this->getEntityManager()->flush($entity);
return true;
}
/**
* @param string $session_id
* @return Entity|null
*/
public function getEntity($session_id)
{
$this->entity = $this->getRepository()->find($session_id);
if (!$this->entity) {
$this->entity = new $this->entityName;
$this->entity->setId($session_id);
}
return $this->entity;
}
// ....
}
new
. Было бы лучше, если бы вы показали свой код. - person akond   schedule 31.07.2017