【问题标题】:Session array storage in Zend Framework 2 throwing warningZend Framework 2 中的会话数组存储抛出警告
【发布时间】:2017-10-09 14:34:46
【问题描述】:

我遇到了Zend\Session\Storage\SessionArrayStorage.php 的问题。我不完全确定发生了什么,因为登录/身份工作正常,并且由于某种原因完全崩溃了。我唯一能想到的就是添加一个分页器路线,但我把它拿出来希望修复错误,但它没有做任何事情。

以下是警告:

Warning: array_key_exists() expects parameter 2 to be array, integer given in C:\xampp\htdocs\vendor\zendframework\zendframework\library\Zend\Session\Storage\AbstractSessionArrayStorage.php on line 400
Warning: Cannot use a scalar value as an array in C:\xampp\htdocs\vendor\zendframework\zendframework\library\Zend\Session\Storage\AbstractSessionArrayStorage.php on line 374

它会多次重复此错误(如果有帮助,这里是错误的屏幕截图 - http://imgur.com/a/do37n

我的设置方式是在Module.php中设置会话服务,并使用文件LoginAuthStorage.php来处理保存,最后通过注册在global.php中的服务调用

这是我认为相关的整个代码:

全局.php

    'service_manager' => array(
          'aliases' => array(
              'Zend\Authentication\AuthenticationService' => 'pblah-auth',
           ),

           'invokables' => array(
               'pblah-auth' => 'Zend\Authentication\AuthenticationService',
           ),


        'session' => array(
            'config' => array(
                'class' => 'Zend\Session\Config\SessionConfig',
                'options' => array(
                    'name' => 'p-blah',
            ),
        ),

        'storage' => 'Zend\Session\Storage\SessionArrayStorage',

        'validators' => array(
            'Zend\Session\Validator\RemoteAddr',
            'Zend\Session\Validator\HttpUserAgent',
        ),
     ),
  ),

模块.php

use Zend\Authentication\Storage;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter as DbTableAuthAdapter;

public function getServiceConfig()
{
    return array(
        'factories' => array(
             'Application\Model\Storage\LoginAuthStorage' => function($sm) {
                 return new LoginAuthStorage();
             },

             'MemberAuthService' => function($sm) {
                  $db_adapter = $sm->get('Zend\Db\Adapter\Adapter');
                  $auth_adapter = new DbTableAuthAdapter($db_adapter, 'members', 'username', 'password');

                  $auth_service = new AuthenticationService();
                  $auth_service->setAdapter($auth_adapter);
                  $auth_service->setStorage($sm->get('Application\Model\Storage\LoginStorage'));

                  return $auth_service;
             }
        ),
    );
}

控制器:

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

use Application\Form\LoginForm;
use Application\Model\Filters\Login;
use Application\Model\Storage\LoginAuthStorage;


class MemberLoginController extends AbstractActionController
{
    protected $storage;
    protected $auth_service;
    protected $login_service;
    protected $mem_service;


    public function indexAction()
    {
        if ($this->getAuthService()->hasIdentity()) {
            return $this->redirect()->toUrl('/members');
        }

        $form = new LoginForm();

        return new ViewModel(array(
            'form' => $form
        ));
    }


    public function authAction()
    {
        $form = new LoginForm();

        $request = $this->getRequest();

        if ($request->isPost()) {

            $login = new Login();

            $form->setInputFilter($login->getInputFilter());
            $form->setData($request->getPost());

            if ($form->isValid()) {
                $login->exchangeArray($form->getData());

                // first make a quick password_verify check
                if (!$this->getLoginService()->verifyPassword($login)) {
                    $this->flashMessenger()->addErrorMessage('Invalid username and/or password');

                    return $this->redirect()->toUrl('login-failure');
                }

                // check first if a session is already active
                if (!$this->getLoginService()->checkSession($login->username)) {
                    $this->flashMessenger()->addErrorMessage("A session is already active with that username.");
                    return $this->redirect()->toUrl('login-failure');
                }

                $this->getAuthService()->getAdapter()
                ->setIdentity($login->username)
                ->setCredential($this->getLoginService()->verifyPassword($login)['pass']);


                $result = $this->getAuthService()->authenticate();

                foreach ($result->getMessages() as $message) {
                    $this->flashMessenger()->addMessage($message);
                }

                if ($result->isValid()) {
                    if ($login->remember_me == 1) {
                        try {
                            $this->getServiceLocator()->get('Application\Model\Storage\LoginAuthStorage')->rememberUser(1);

                            $this->getAuthService()->setStorage($this->getServiceLocator()->get('Application\Model\Storage\LoginAuthStorage'));

                            $this->getLoginService()->insertSession($login->username,
                                $this->getLoginService()->verifyPassword($login)['pass'], session_id());
                        } catch (\Exception $e) {
                            echo $e->getMessage();
                        }
                    } else if ($login->remember_me == 0) {
                        try {
                            $this->getServiceLocator()->get('Application\Model\Storage\LoginAuthStorage')->rememberUser(0);

                            $this->getAuthService()->setStorage($this->getServiceLocator()->get('Application\Model\Storage\LoginAuthStorage'));

                            $this->getLoginService()->insertSession($login->username,
                                $this->getLoginService()->verifyPassword($login)['pass'], session_id());
                        } catch (\Exception $e) {
                            echo $e->getMessage();
                        }
                    }

                    $this->getAuthService()->getStorage()->write($login->username);

                    return $this->redirect()->toUrl('/members');
                } else {
                    $this->flashMessenger()->addErrorMessage('Invalid username and/or password');

                    return $this->redirect()->toUrl('login-failure');
                }
            } else {
                return new ViewModel(array('form_error' => 'Validation Error while logging in, please try again.'));
            }
        }
    }


    public function loginfailureAction()
    {
        return new ViewModel(array());
    }


    public function getAuthService()
    {
        if (!$this->auth_service) {
            $this->auth_service = $this->getServiceLocator()->get('MemberAuthService');
        }

        return $this->auth_service;
    }


    public function getLoginService()
    {
        if (!$this->login_service) {
            $this->storage = $this->getServiceLocator()->get('Application\Model\LoginModel');
        }

        return $this->storage;
    }
}

登录验证存储

   namespace Application\Model\Storage;

use Zend\Authentication\Storage\Session;


class LoginAuthStorage extends Session
{
    /**
     * Sets the time for the user to be remembered after login
     * @param number $default
     * @param number $time
     * @return void
     */
    public function rememberUser($default = 0, $time = 1209600)
    {
        if ($default == 1) {
            $this->session->getManager()->rememberMe($time);
        } else if ($default == 0) {
            $this->session->getManager()->rememberMe(0);
        }
    }


    /**
     * Destroys the session information
     * @return void
     */
    public function forgetUser()
    {
        $this->session->getManager()->forgetMe();
    }
}

index.phtml($this->identity() 被调用的地方)

<h4 class="w3-center"><?php echo "Welcome " . $this->identity(); ?></h4>

和成员控制器 -

 namespace Members\Controller;

use Zend\Mvc\Controller\AbstractActionController;



class MembersController extends AbstractActionController
{
    protected $profile_service;
    protected $groups_service;


    public function indexAction()
    {
        $params = $this->identity();

        $dir = array_diff(scandir(getcwd() . '/public/images/profile/' . $params . '/', 1), array('.', '..', 'current', '.htaccess'));

        if (count($dir) > 0) {
            $images = array();

            foreach ($dir as $value) {
                $images[] = "<img src=\"/images/profile/$params/$value\" class=\"w3-margin-bottom w3-round w3-border\" style=\"width: 100%; height: 88px;\">";
            }

            $layout = $this->layout();

            natsort($images);

            $layout->setVariable('my_images', $images);
        }
    }


    public function getProfileService()
    {
        if (!$this->profile_service) {
            $this->profile_service = $this->getServiceLocator()->get('Members\Model\ProfileModel');
        }

        return $this->profile_service;
    }


    public function getGroupsService()
    {
        if (!$this->groups_service) {
            $this->groups_service = $this->getServiceLocator()->get('Members\Model\GroupsModel');
        }

        return $this->groups_service;
    }
}

如果它也有帮助,这里是 Members Module.php

namespace Members;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Http;
use Members\Model\ProfileModel;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Members\Model\Filters\EditProfile;
use Members\Model\EditProfileModel;
use Members\Model\GroupsModel;


class Module implements AutoloaderProviderInterface
{

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . str_replace('\\', '/' , __NAMESPACE__),
                ),
            ),
        );
    }


    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }


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

        $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'checkCredentials'));
        $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'configureLayout'));
    }


    public function checkCredentials(MvcEvent $e)
    {
        $matches = $e->getRouteMatch();

        if (!$matches) {
            return $e;
        }

        $route = $matches->getMatchedRouteName();

        if (0 !== strpos($route, 'members/') && $route !== 'members') {
            return $e;
        }

        $auth_service = $e->getApplication()->getServiceManager()->get('pblah-auth');

        if (!$auth_service->hasIdentity()) {
            $response = $e->getResponse();
            $response->setStatusCode(302);
            $response->getHeaders()
            ->addHeaderLine('Location', $e->getRouter()->assemble([], array('name' => 'home/member-login')));
            $response->sendHeaders();
            return $response;
        }

        return $e;
    }


    public function configureLayout(MvcEvent $e)
    {
        if ($e->getError()) {
            return $e;
        }

        $request = $e->getRequest();

        if (!$request instanceof Http\Request || $request->isXmlHttpRequest()) {
            return $e;
        }

        $matches = $e->getRouteMatch();

        if (!$matches) {
            return $e;
        }

        $app = $e->getParam('application');
        $layout = $app->getMvcEvent()->getViewModel();

        $controller = $matches->getParam('controller');

        $module = strtolower(explode('\\', $controller)[0]);

        if ('members' === $module) {
            $layout->setTemplate('layout/members');
        }
    }


    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Members\Module\EditProfileModel' => function ($sm) {
                    $table_gateway = $sm->get('EditProfileService');
                    $profile = new EditProfileModel($table_gateway);
                    return $profile;
                },

                'EditProfileService' => function ($sm) {
                    $db_adapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $result_set_prototype = new ResultSet();
                    $result_set_prototype->setArrayObjectPrototype(new EditProfile());
                    return new TableGateway('profiles', $db_adapter, null, $result_set_prototype);
                },

                'Members\Model\ProfileModel' => function ($sm) {
                    $table_gateway = $sm->get('ProfileService');
                    $profile = new ProfileModel($table_gateway, $sm->get('pblah-auth')->getIdentity());

                    return $profile;
                },

                'ProfileService' => function ($sm) {
                    $db_adapter = $sm->get('Zend\Db\Adapter\Adapter');
                    return new TableGateway('profiles', $db_adapter);
                },

                'Members\Model\GroupsModel' => function ($sm) {
                    $table_gateway = $sm->get('GroupsService');
                    $group_model = new GroupsModel($table_gateway, $sm->get('pblah-auth')->getIdentity());

                    return $group_model;
                },

                'GroupsService' => function ($sm) {
                    $db_adapter = $sm->get('Zend\Db\Adapter\Adapter');
                    return new TableGateway('groups', $db_adapter);
                }
            ),
        );
    }
}

我确实检查了$this-&gt;identity() 以查看它是否正常工作并且它正在传递用户名,但同样,这两个警告只是多次出现在页面上。

如果需要更多信息,我可以尝试发布更多信息。

【问题讨论】:

  • 'pblah-auth' =&gt; 'Zend\Authentication\AuthenticationService' 替换为'pblah-auth' =&gt; 'Zend\ServiceManager\Factory\InvokableFactory' 会发生什么? (假设您使用的是最新版本的框架)
  • @User210411 你找到解决方案了吗?

标签: php session zend-framework


【解决方案1】:

看起来好像会话全局变量在$_SESSION['__ZF']中包含一个整数而不是一个数组。

您可以尝试像这样转储$_SESSION 变量以查看其中的实际内容:

\Zend\Debug\Debug::dump($_SESSION);

接下来,尝试清除会话,然后再次查看登录后会发生什么。

【讨论】:

  • 它说它是空的。我已经注销并重新登录,但它仍在这样做。
  • 尝试在应用程序开始执行任何操作之前转储它,然后使用常规的var_dump。另外,您是否尝试过从浏览器中清除会话或在 PHP 中取消设置?
  • 是的,我在浏览器中清除了会话,然后注销调用了之前工作正常的忘记用户()和 clearIdentity(),我不确定。
  • 它让我登录,但每当我调用 $this->identity() 时,它都会显示警告(至少我认为这是问题所在)
  • 您能否编辑您的帖子以反映$this-&gt;identity() 的名称?可能是在它可用之前就被调用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2015-03-23
相关资源
最近更新 更多