您如何设置会话命名空间?

时间:2019-05-22 21:48:04

标签: php zend-framework3

我对Zend并不陌生,我正在尝试设置会话名称空间变量。我收到一条错误消息,指出“配置缺少“ session_config”键,或者该键的值不是数组”。

我一直遵循Zend提供的有关该主题的文档,但是我对这两者之间的联系方式略有欠缺。

我已经在全局配置文件中配置了会话管理器,如下所示:

    'session_manager' => [
        'config' => [
            'class' => Session\Config\SessionConfig::class,
            'options' => [
                'name' => 'user',
            ],
        ],
        'storage' => Session\Storage\SessionArrayStorage::class,
        'validators' => [
            Session\Validator\RemoteAddr::class,
            Session\Validator\HttpUserAgent::class,
        ],
    ],

我在Module类中创建了会话管理器,如下所示:

use Zend\Session\SessionManager;
use Zend\Session\Config\SessionConfig;
use Zend\Session\Container;
use Zend\Session\Validator;
use Zend\Mvc\ModuleRouteListener;

class Module implements ConfigProviderInterface
{

    public function onBootstrap($e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
        $this->bootstrapSession($e);
    }

    public function bootstrapSession($e)
    {
        $session = new SessionManager();
        $session->start();

        $container = new Container('initialized');

        if (isset($container->init)) {
            return;
        }

        $serviceManager = $e->getApplication()->getServiceManager();
        $request        = $serviceManager->get('Request');

        $session->regenerateId(true);
        $container->init          = 1;
        $container->remoteAddr    = $request->getServer()->get('REMOTE_ADDR');
        $container->httpUserAgent = $request->getServer()->get('HTTP_USER_AGENT');

        $config = $serviceManager->get('Config');
        if (! isset($config['session'])) {
            return;
        }

        $sessionConfig = $config['session'];

        if (! isset($sessionConfig['validators'])) {
            return;
        }

        $chain   = $session->getValidatorChain();

        foreach ($sessionConfig['validators'] as $validator) {
            switch ($validator) {
            case Validator\HttpUserAgent::class:
                    $validator = new $validator($container->httpUserAgent);
                    break;
                    case Validator\RemoteAddr::class:
                    $validator  = new $validator($container->remoteAddr);
                    break;
                default:
                    $validator = new $validator();
            }

            $chain->attach('session.validate', array($validator, 'isValid'));
        }
    }

    public function getServiceConfig()
    {
        return [
            'factories' => [
                SessionManager::class => function ($container) {
                    $config = $container->get('config');
                    if (! isset($config['session'])) {
                        $sessionManager = new SessionManager();
                        Container::setDefaultManager($sessionManager);
                        return $sessionManager;
                    }

                    $session = $config['session'];

                    $sessionConfig = null;
                    if (isset($session['config'])) {
                        $class = isset($session['config']['class'])
                            ?  $session['config']['class']
                            : SessionConfig::class;

                        $options = isset($session['config']['options'])
                            ?  $session['config']['options']
                            : [];

                        $sessionConfig = new $class();
                        $sessionConfig->setOptions($options);
                    }

                    $sessionStorage = null;
                    if (isset($session['storage'])) {
                        $class = $session['storage'];
                        $sessionStorage = new $class();
                    }

                    $sessionSaveHandler = null;
                    if (isset($session['save_handler'])) {
                        // class should be fetched from service manager
                        // since it will require constructor arguments
                        $sessionSaveHandler = $container->get($session['save_handler']);
                    }

                    $sessionManager = new SessionManager(
                        $sessionConfig,
                        $sessionStorage,
                        $sessionSaveHandler
                    );

                    Container::setDefaultManager($sessionManager);
                    return $sessionManager;
                },
            ],
        ];
    }

我在module.config.php文件中定义了会话容器名称空间,如下所示:

    'session_containers' => [
        'UserNamespace'
    ],

我尝试如下访问控制器工厂中的名称空间:

namespace User\Factory;

use Interop\Container\ContainerInterface;
use Zend\Authentication\AuthenticationService;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\Session\Container;
use User\Controller\AuthController;
use User\Model\UserRepositoryInterface;
use User\Form\LoginForm;

class AuthControllerFactory implements FactoryInterface
{
    /**
     * @param ContainerInterface $container
     * @param string $requestedName
     * @param null|array $options
     * @return AuthController
     */
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $formManager = $container->get('FormElementManager');
        $sessionContainer = $container->get('UserNamespace');
        return new AuthController(
            $container->get(UserRepositoryInterface::class),
            $formManager->get(LoginForm::class),
            $sessionContainer
        );
    }
}

最后,我尝试按如下所示在控制器中调用会话名称空间变量:

namespace User\Controller;

use User\Form\LoginForm;
use User\Model\User;
use User\Model\UserRepositoryInterface;
use Zend\Session\Container;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class AuthController extends AbstractActionController
{
    /**
     * @var UserRepositoryInterface
     */
    private $userRepository;

    /**
     * @var LoginForm
     */
    private $loginForm;

    private $sessionContainer;

    /**
     * @param UserRepositoryInterface $userRepository
     * @param LoginForm $loginForm
     */
    public function __construct(
        UserRepositoryInterface $userRepository,
        LoginForm $loginForm,
        $sessionContainer
    ) {
        $this->userRepository = $userRepository;
        $this->loginForm = $loginForm;
        $sessionContainer;
    }

    public function loginAction()
    {
        $request    = $this->getRequest();
        $viewModel  = new ViewModel(['form' => $this->loginForm]);

        if (! $request->isPost()) {
            return $viewModel;
        }

        $this->loginForm->setData($request->getPost());

        if (! $this->loginForm->isValid()) {
            return $viewModel;
        }

        $loginAttempt = $this->loginForm->getData();

        // var_dump($loginAttempt); die;

        try {
            $user = $this->userRepository->retrieveUserByUsername($loginAttempt['username']);
        } catch (\Exception $ex) {
            throw $ex;
        }

        // var_dump($user); die;

        try {
            $isLogin = $this->userRepository->validatePassword($user, $loginAttempt['password']);
        } catch (\Exception $ex) {
            throw $ex;
        }

        // var_dump($isLogin); die;

        if($isLogin == true) {
            $sessionContainer->test = "This is a test";
        }

        var_dump($sessionContainer->test); die;
    }

我确信我在执行这项工作的过程中会感到有些困惑,因此,您能提供的任何帮助或建议将不胜感激。

0 个答案:

没有答案