【问题标题】:Updating Zend_Auth storage after editing a user编辑用户后更新 Zend_Auth 存储
【发布时间】:2026-01-27 18:30:01
【问题描述】:

我使用 Zend_Auth 对用户进行身份验证,然后将他们的详细信息存储在默认的 Zend_Auth 会话中。这意味着当用户编辑他的详细信息时,这些更改不会反映在应用程序中,直到他重新进行身份验证。

我想这样避免这个问题:

  1. 当用户登录时,我们只将他的 user ID 存储在 Zend_Auth 会话中
  2. 在每个请求中,我们使用user IDpreDispatch() 挂钩中从数据库中获取用户的详细信息,该user ID 在登录时存储在Zend_Auth 会话中:

    class Plugin_Auth extends Zend_Controller_Plugin_Abstract
    {
    
        public function preDispatch(Zend_Controller_Request_Abstract $request)
        {
            if ($auth->hasIdentity())
            {
                $id = $auth->getIdentity()->id;
    
                $userModel = new Model_User();
    
                $user = $userModel->fetchOne($id);
    
                // Where do I store this user object ???
            }
    
        }
    }
    
  3. 问题是:我在哪里存储这个User 对象?我认为我们不应该为此使用会话,因为会话的目标是持久化数据。但是不需要持久性,因为我们在每次请求时都从数据库中重新获取数据。只有user ID 必须是持久的。将User 对象存储在Zend_Registry 中是一种选择吗?

【问题讨论】:

  • 将重新身份验证作为更改用户配置文件的一部分是否不合适。毕竟,您需要确保用户实际上是用户。这是重新验证和更新存储的好时机。

标签: zend-framework zend-auth


【解决方案1】:

我认为示例将是解释如何将新的身份验证详细信息写入 Zend_Auth 存储对象的最佳示例:

$userDetails = array('foo' => 'bar');
$storage = new Zend_Auth_Storage_Session();
// set sorage for Zend_Auth
Zend_Auth::getInstance()->setStorage($storage);
// write data to the storage
Zend_Auth::getInstance()->getStorage()->write($userDetails);
// read data from storage
var_dump(Zend_Auth::getInstance()->getStorage()->read());
// edit user's data
$userDetails = array('foo' => 'bar', 'foo', 'bar');
// write new data to storage
Zend_Auth::getInstance()->getStorage()->write($userDetails);
// read new written data from storage
var_dump(Zend_Auth::getInstance()->getStorage()->read());

我认为这解释了如何设置 Zend_Auth 存储,并在以后更改它。

【讨论】:

  • 您刚刚描述了如何将数据添加到默认的Zend_Auth 会话存储机制中。我已经知道该怎么做。通过将所有用户详细信息存储在会话中,对这些详细信息的更改只会在用户重新进行身份验证时反映出来。
  • 您已编辑问题。 Anywho 为什么您不会将用户对象存储在会话中(可以作为数组),并且仅在用户编辑其详细信息而不在每个请求上获取用户数据时才重写它?如果此选项不适合您,您始终可以在 User_Model 中使用名为“getCurrentUser”的静态字段 $user 方法,并在查询完成一次时始终从该方法获取用户数据。
【解决方案2】:

使用Zend_Session_Namespace 来存储对象。它可以是临时的,也可以是永久的,只要你愿意。

Zend_Auth 已经在后台使用它,因为它是使用 Zend_Auth 命名空间的默认存储机制。

class Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $session = new Zend_Session_Namespace('user');//instantiate session namespace
        if ($auth->hasIdentity())
        {
            $id = $auth->getIdentity()->id;

            $userModel = new Model_User();

            $user = $userModel->fetchOne($id);

            $session->user = $user;//store the object can be recalled anywhere
        }
    }
}

当然,Zend_Registry 也能正常工作,而且一如既往地由您选择。您甚至可能会发现将此功能构建到您的身份验证适配器中是合适的。

【讨论】:

    【解决方案3】:

    我相信在您的情况下使用 Zend_Registry 没问题。

    【讨论】: