ZF2, исключение возникло при создании слушателя & amp; Проверка сеанса не удалась

Давайте начнем с того, что идет не так: у меня есть прослушиватель acl, связанный с событием «route», который на первый взгляд работает нормально, но через некоторое время выдает пару ошибок. Это ошибки:

Неустранимая ошибка: необработанное исключение
‘Zend \ Session \ Exception \ RuntimeException’ с сообщением ‘Session
проверка не удалась’…

Zend \ ServiceManager \ Exception \ ServiceNotCreatedException: исключение
был поднят при создании «authService»; экземпляр не возвращен …

Zend \ ServiceManager \ Exception \ ServiceNotCreatedException: исключение
был поднят при создании «MyAclListener»; экземпляр не возвращен …

Слушатель настроен следующим образом:

class MyAclListener implements ListenerAggregateInterface
{
/** @var  AuthenticationServiceInterface */
protected $_authService;

function __construct (
AuthenticationServiceInterface $authService ,
)
{
$this->_authService     = $authService;
}

public function attach ( EventManagerInterface $events )
{

$this->listeners[ ] = $events->attach( 'route' , array( $this , 'checkAcl' ) );
}

public function checkAcl( MvcEvent $e ) {
\\\Do Something for which the authService is needed
}

Затем в module.config.php у меня есть

$config = array(
'service_manager' => array(
'factories' => array(
'MyAclListener' => 'MyAcl\Factory\MyAclListenerFactory'
) ,
) ,
'listeners'       => array(
'MyAclListener'
) ,
);

Фабрика для слушателя:

<?php

namespace MyAcl\Factory;

use MyAcl\Listener\MyAclListener;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class AclListenerFactory implements FactoryInterface
{

public function createService(ServiceLocatorInterface $serviceLocator)
{

// Finally create the service
return new MyAclListener(
$serviceLocator->get('authService') ,
);
}

}

Сессия настроена в Module.php

   public function onBootstrap ( MvcEvent $e )
{

$serviceManager         = $e->getApplication()->getServiceManager();

$config = $serviceManager->get('Configuration');
$this->initSession( $config['session'] , $serviceManager->get('sessionCache')  );
}

public function initSession ( $config , $cache )
{

$sessionConfig = new SessionConfig();
$sessionConfig->setOptions( $config );
$sessionManager = new SessionManager( $sessionConfig );

$saveHandler = new Cache($cache);
$sessionManager->setSaveHandler( $saveHandler );

$sessionManager->getValidatorChain()->attach('session.validate', array(new HttpUserAgent(), 'isValid'));
$sessionManager->getValidatorChain()->attach('session.validate', array(new RemoteAddr(), 'isValid'));

$sessionManager->start();
$sessionManager->regenerateId(true);

}

И это соответствующие конфиги для сессии:

$config = array(
'session'         => array(
'cookie_lifetime' => 28800 ,
'remember_me_seconds' => 28800 ,
'use_cookies'         => true ,
'cookie_httponly'     => true ,
) ,
'caches'          => array(
'sessionCache' => array(
'adapter' => array(
'name'     => 'memcached' ,
'lifetime' => 604800 ,
'options'  => array(
'servers'    => array(
array(
'127.0.0.1' , 11211
)
) ,
'namespace'  => 'MySessionCache' ,
'liboptions' => array(
'COMPRESSION'     => true ,
'binary_protocol' => true ,
'no_block'        => true ,
'connect_timeout' => 100
)
) ,
'plugins'  => array( 'serializer' )
) ,
) ,
) ,
)

Также может быть полезно знать, что после ошибки моя «личность» утеряна, а вошедший в систему пользователь вышел из системы.

Итак, что я делаю не так? Как мне избавиться от этих ошибок? Может быть, даже: есть ли лучшие решения для настройки проверки ACL и моих сеансов?

ОБНОВИТЬ
Я изменил настройки сеанса:

В Module.php

    public function onBootstrap ( MvcEvent $e )
{

$serviceManager = $e->getApplication()->getServiceManager();

/* session */
$this->expandInitialSessionConfig( $serviceManager , $serviceManager->get( 'sessionCache' ) );
}

public function expandInitialSessionConfig ( $sm , $cache )
{

/** @var \Zend\Session\SessionManager $sessionManager */
$sessionManager = $sm->get( 'Zend\Session\SessionManager' );

$saveHandler = new Cache( $cache );
$sessionManager->setSaveHandler( $saveHandler );

$sessionManager->getValidatorChain()->attach( 'session.validate' , array( new HttpUserAgent() , 'isValid' ) );
$sessionManager->getValidatorChain()->attach( 'session.validate' , array( new RemoteAddr() , 'isValid' ) );

}

В module.config.php

return array(
'session_config'  => array(
'cookie_lifetime'     => 28800 ,
'remember_me_seconds' => 28800 ,
'use_cookies'         => true ,
'cookie_httponly'     => true ,
'gc_probability'      => 10 ,
'gc_maxlifetime'      => 7200 ,
'cookie_domain'       => 'mydomain.com' ,
) ,
'service_manager' => array(
'factories' => array(
'Zend\Session\SessionManager'         => 'Zend\Session\Service\SessionManagerFactory' ,
'Zend\Session\Config\ConfigInterface' => 'Zend\Session\Service\SessionConfigFactory' ,
) ,
);

И $ sessionManager-> recycrateId (true) был перемещен, так что теперь это происходит только при входе в систему.

0

Решение

Вы спрашиваете ServiceLocator в вашем AclListenerFactory для authService но он не может найти ничего подобного, что вызывает второе исключение.
Поскольку authService не найден, ваша фабрика не возвращает слушателя. Это последнее исключение.

В своем коде вы пишете:

$serviceLocator->get('authService') ,

Первое исключение связано с ошибкой проверки сеанса. Причина всех проблем лежит, вероятно, там. Нет результатов проверки сессии, вероятно, нет authService таким образом соединяя в цепочку другие два исключения.
Где это authService зарегистрирован или создан? Это не видно в коде, которым вы делитесь в настоящее время. И как эта служба полагается на «проверку», которая не проходит …

Если вы решите проблему с проверкой сеанса, возможно, все будет хорошо.

1

Другие решения

Я серьезно сомневаюсь, что это «лучшая практика», но удаляя из конструктора моего слушателя те зависимости (которые были добавлены после первоначального вопроса), которые, в свою очередь, зависят от сеанса, решили проблему. Я знаю, что получаю их из ServiceLocator в первый момент, когда они мне нужны в моем коде, и храню их в защищенном параметре моего класса слушателя для дальнейшего использования. Однако, как я уже сказал, это больше не правильное внедрение зависимостей, но, по крайней мере, это работает.

function __construct (Logger $_myLog )
{
$this->_myLog          = $_myLog;
// removed here: $this->_authService     = $authService;

}

Затем:

public function checkAcl ( MvcEvent $e )
{
$sm = $e->getApplication()->getServiceManager();
$this->_authService = $sm->get('authService');
....
}
0

По вопросам рекламы [email protected]