在会话中序列化对象时 PHP 类不完整

发布于 2024-11-05 08:19:37 字数 1301 浏览 3 评论 0原文

我正在开发购物车(购物车模型)。它的受保护属性之一是“_items”,它包含 Product 对象的数组。它们(产品)都存储在数据库中用于填充会话(使用 ZF、Zend_Session_SaveHandler_DbTable() 等)。

public function addItem(Model_Product $product, $qty)
{
    $qty = (int) $qty;
    $pId = $product->getId();

    if ($qty > 0) {
        $this->_items[$pId] = array('product' => $product, 'qty' => $qty);
    } else {
        // if the quantity is zero (or less), remove item from stack
        unset($this->_items[$pId]);
    }

    // add new info to session
    $this->persist();
}

在控制器中,我使用 ProductMapper 从数据库获取 Product 对象,并将其提供给“addItem()”:

    $product1 = $prodMapper->getProductByName('cap');
    $this->_cart->addItem($product1, 2);

getProductByName() 返回一个新填充的 Model_Product 对象。


我通常会收到

请确保您尝试操作的对象的类定义“Model_Product”已加载_before_ ...

错误消息,会话转储明显显示

['__PHP_Incomplete_Class_Name' ] => 'Model_Product'


我知道“在序列化之前声明类”。我的问题是:如果首先注入了 Product 类(第一个参数),如何在 addItem() 中声明 Product 类?新的声明(例如 new Model_Product())不会覆盖 addItem() 中的参数(原始对象)吗?我必须在 Cart 模型中再次声明吗?

此外,如果我...在购物车中重新声明它,我肯定会得到一个 Cannot redeclare class Model_Product

I'm working on a shopping cart (Cart model). One of its protected properties is "_items", which holds an array of Product objects. They (Products) all get stored in DB for populating the session (using ZF, Zend_Session_SaveHandler_DbTable() etc.).

public function addItem(Model_Product $product, $qty)
{
    $qty = (int) $qty;
    $pId = $product->getId();

    if ($qty > 0) {
        $this->_items[$pId] = array('product' => $product, 'qty' => $qty);
    } else {
        // if the quantity is zero (or less), remove item from stack
        unset($this->_items[$pId]);
    }

    // add new info to session
    $this->persist();
}

In the controller, I grab a Product obj from DB with the ProductMapper and provide it to "addItem()":

    $product1 = $prodMapper->getProductByName('cap');
    $this->_cart->addItem($product1, 2);

getProductByName() returns a new populated Model_Product object.


I usually get the

Please ensure that the class definition "Model_Product" of the object you are trying to operate on was loaded _before_ ...

error message, a session dump obviously shows

['__PHP_Incomplete_Class_Name'] => 'Model_Product'


I know about the "declaring the class before serializing it". My problem is this: how can I declare the Product class in addItem(), if it's injected (first param) in the first place? Wouldn't a new declaration (like new Model_Product()) overwrite the param (original object) in addItem()? Must I declare it in the Cart model again?

Besides, I'll surely get a Cannot redeclare class Model_Product if I... redeclare it in Cart.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

抠脚大汉 2024-11-12 08:19:37

在 ZF 的引导程序中,会话在自动加载之前启动。

    /**
     * Make XXX_* classes available
     */
    protected function _initAutoloaders()
    {
        $loader = new Zend_Application_Module_Autoloader(array(
                    'namespace' => 'XXX',
                    'basePath' => APPLICATION_PATH
                ));
    }

    public function _initSession()
    {
        $config = $this->_config->custom->session;

        /**
         * For other settings, see the link below:
         * http://framework.zend.com/manual/en/zend.session.global_session_management.html
         */
        $sessionOptions = array(
            'name'             => $config->name,
            'gc_maxlifetime'   => $config->ttl,
            'use_only_cookies' => $config->onlyCookies,
//            'strict'           => true,
//            'path'             => '/',
        );

        // store session info in DB
        $sessDbConfig = array(
            'name'           => 'xxx_session',
            'primary'        => 'id',
            'modifiedColumn' => 'modified',
            'dataColumn'     => 'data',
            'lifetimeColumn' => 'lifetime'
        );

        Zend_Session::setOptions($sessionOptions);
        Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($sessDbConfig));
        Zend_Session::start();
    }

当我遇到我所说的错误时,方法声明是相反的:首先是 _initSession(),然后是 _initAutoloaders() - 这就是确切的订单 ZF 正在处理它们。

我会进行更多测试,但这似乎有效(并且合乎逻辑)。感谢您的所有建议。

In ZF's bootstrap, the session was started before autoloading.

    /**
     * Make XXX_* classes available
     */
    protected function _initAutoloaders()
    {
        $loader = new Zend_Application_Module_Autoloader(array(
                    'namespace' => 'XXX',
                    'basePath' => APPLICATION_PATH
                ));
    }

    public function _initSession()
    {
        $config = $this->_config->custom->session;

        /**
         * For other settings, see the link below:
         * http://framework.zend.com/manual/en/zend.session.global_session_management.html
         */
        $sessionOptions = array(
            'name'             => $config->name,
            'gc_maxlifetime'   => $config->ttl,
            'use_only_cookies' => $config->onlyCookies,
//            'strict'           => true,
//            'path'             => '/',
        );

        // store session info in DB
        $sessDbConfig = array(
            'name'           => 'xxx_session',
            'primary'        => 'id',
            'modifiedColumn' => 'modified',
            'dataColumn'     => 'data',
            'lifetimeColumn' => 'lifetime'
        );

        Zend_Session::setOptions($sessionOptions);
        Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($sessDbConfig));
        Zend_Session::start();
    }

When I was getting the errors I was talking about, the method declaration was the other way around: _initSession() was first, then _initAutoloaders() - and this was the exact order ZF was processing them.

I'll test some more, but this seems to work (and logical). Thanks for all your suggestions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文