Я реализовал логику в загрузочном модуле приложения, которая будет перенаправлять пользователей на страницу входа, если они не подписаны. я имею
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$session = new Container('signin');
if (!isset($session->member)){
$eventManager->attach(MvcEvent::EVENT_ROUTE, array($this,'routeMatched'), -100);
}
}
public function routeMatched(MvcEvent $e)
{
$match = $e->getRouteMatch();
// No route match, this is a 404
if (!$match instanceof RouteMatch) {
return;
}
$list = array('login', 'signin', 'upload');
// Route is whitelisted
$name = $match->getMatchedRouteName();
if (in_array($name, $list)) {
return;
}
// Redirect to the user login page, as an example
$router = $e->getRouter();
$url = $router->assemble(array(), array(
'name' => 'signin'
));
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}
}
Как вы можете увидеть ниже код внутри onBootstrap
проверит, если контейнер сеанса не имеет member
переменная установлена или нет, если она не установлена, то присоединяется EVENT_ROUTE, который внутренне обрабатывает, что делать в зависимости от того, указан ли текущий маршрут в списке белого цвета или нет.
$session = new Container('signin');
if (!isset($session->member)) ...
Проблема здесь в том, что $session->member
всегда становится null
, Я назначаю эту переменную в действии входа в систему в моем контроллере, как это
if ($data->authenticate($member->email, $member->password)){
$session = new Container('signin');
$session->member = $member;
return $this->redirect()->toRoute('member-control-panel');
}else{
$view->setVariable('error', 'Could not verify user/password');
}
В чем здесь проблема?
Обновить:
Я внес изменения, предложенные Уилтсом в его ответе. Это все еще не работало, но я немного изменил код, чтобы хранить скалярное значение (электронная почта) вместо объекта (члена). Теперь это работает, поэтому вопрос почему контейнер сеанса не хранит объект, а только скалярные переменные?
В моем действии входа я сделал такие изменения
$session = new Container('signin');
//$session->member = $member; //removed
$session->email= $member->email; //New
В бутстрапе вот так
$session = new Container('signin');
if (!isset($session->email)){
$eventManager->attach(MvcEvent::EVENT_ROUTE, array($this,'routeMatched'), -100);
}
Правильная обработка сессий включает в себя гораздо больше, чем просто сброс ваших переменных в Container
пример. Сеанс не может хранить объекты без их сериализации. Это означает, что вы должны снова десериализовать их при разрешении из сессии.
Чтобы помочь вам в управлении сессионным хранилищем, ZF2 имеет SessionManager
класс я предлагаю вам создать SessionManager
чтобы получить контроль над вашими переменными сеанса. Вы можете прочитать больше в официальные документы ZF2 о том, как правильно обрабатывать сессии.
Вы запускаете сессию так:
use Zend\Session\SessionManager;
use Zend\Session\Container;
class Module
{
public function onBootstrap($event)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$this->bootstrapSession($event);
}
public function bootstrapSession($e)
{
$session = $e->getApplication()
->getServiceManager()
->get('Zend\Session\SessionManager');
$session->start();
$container = new Container('signin');
}
}
Если твой $member
это сущность учения, я бы также предложил прочитать Доктрина 2 документации по хранению сущностей в сеансе
Других решений пока нет …