Magento:缓存集合上的序列化错误 [英] Magento: serialization error on caching Collection

查看:79
本文介绍了Magento:缓存集合上的序列化错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个扩展,其中一个基本抽象类包含一个将提取产品集合的函数:

I wrote an extension in which a base abstract class contains a function that will extract a product collection:

$cache = Mage::app()->getCache();
        if(!$cache->load('itserv_feed_collection')) {
            $_productCollection = Mage::getModel('catalog/product')->getCollection();
            $_productCollection->addAttributeToSelect('*');                        
            $_productCollection->addAttributeToSelect('stock_status');        
            $_productCollection->addAttributeToSelect(Mage::getStoreConfig('feed_options/mappa_attributi/produttore'));
            $_productCollection->addAttributeToSelect(Mage::getStoreConfig('feed_options/mappa_attributi/ean'));
            $_productCollection->addAttributeToSelect(Mage::getStoreConfig('feed_options/mappa_attributi/mpn'));      
            $_productCollection->addAttributeToFilter('type_id', Mage_Catalog_Model_Product_Type::TYPE_SIMPLE);                                                                       
            $cache->save(serialize($_productCollection), "itserv_feed_collection", array("itserv_feed_collection"), 120);                
        }
        else {                
            $_productCollection = unserialize($cache->load('itserv_feed_collection'));
        }
        return $_productCollection;

从该类扩展的每个子类将在相同的运行时堆栈中使用相同的集合.我想将此集合保存在缓存中(如您在代码中所见),因此,由于子类第二次使用它,因此脚本无需再次加载它.

Each of the child classes extending from this class will use the same collection in the same runtime stack. I want to save this collection within the cache (as you can see looking at the code), so since the second time a child class will use it, the script will not need to load it again.

问题在于无法使用缓存,因为缓存需要一个序列化的Collection,在这种情况下,我无法做到这一点,因为该集合包含无法序列化的Mage_Core_Model_Config_Element(它会触发著名的错误序列化" 'Mage_Core_Model_Config_Element'的值".

The problem is that it is impossible to use cache, because cache needs a serialized Collection and, in this case, i cannot do it because the collection contains the Mage_Core_Model_Config_Element that can't be serialized (it triggers the famous error "Serialization of 'Mage_Core_Model_Config_Element' is not allowed").

我尝试了不同的解决方案,甚至使用json_encode/json_decode而不是序列化/反序列化,但我无法解决问题.

I tried different solutions, even json_encode/json_decode instead of serialize/unserialize, but i can't solve the problem.

您有解决方案吗?谢谢!

Do you have some solution? Thanks!

推荐答案

这可能会有点晚,但希望将来能使某人走上正确的道路.

this may be a bit late but hopefully will put someone on the right track in the future.

正如您所注意到的,您无法序列化集合,但是您可以将返回的项目作为数组获取并缓存它们.这是第1步.

As you noticed, you cannot serialize the collection, but you can get the returned items as an array and cache those. This is step 1.

然后,根据您使用集合的方式(例如在产品列表上)和调用count(),Magento将尝试再次加载集合,由于IsLoaded标志将为false,因此会导致错误,但是您将有项目.

Then, depending on how you use the collection (for example on a product list) and count() is called, Magento will try to load the collection again, resulting in an error since the IsLoaded flag will be false, but you will have the items.

要解决此问题,您需要在将项目添加到集合后设置标志.为此,您应该重写产品资源集合(以访问此标志).因此,按代码进行:

To solve this, you need to set the flag after adding the items to the collection. In order to do so, you should rewrite the product resource collection (to get access to this flag). So codewise:

该代码基于您要在产品列表页面上使用集合的假设,并且不支持排序/过滤等,因为仅缓存项目.

The code is based on the assumption you want to use the collections on the product list page and does not support sorting / filtering etc, since only the items are cached.

第1步: 添加产品列表和产品资源集合的重写:

Step 1: Add the rewrites for the product list and product resource collection:

<config>
    <global>
        <blocks>
            <projectName>
                <class>CompanyName_ProjectName_Block</class>
            </projectName>
            <catalog>
                <rewrite>
                    <product_list>CompanyName_ProjectName_Block_Catalog_Product_List</product_list>
                </rewrite>
            </catalog>
        </blocks>
        <models>
            <projectName>
                <class>CompanyName_ProjectName_Model</class>
            </projectName>
            <catalog_resource>
                <rewrite>
                    <product_collection>CompanyName_ProjectName_Model_Resource_Product_Collection</product_collection>
                </rewrite>
            </catalog_resource>
        </models>
    </global>
<config>

第2步:创建Resource类

Step 2: Create the Resource class

<?php
class CompanyName_ProjectName_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
{
    public function setIsLoaded($flag)
    {
        $this->_setIsLoaded($flag);
    }
}

第3步:创建执行实际缓存加载的产品列表类

Step 3 : Create the product list class that does the actual caching loading

<?php
class CompanyName_ProjectName_Block_Catalog_Product_List extends Mage_Catalog_Block_Product_List
{   
    public function getCachedLoadedProductCollection()
    {
        $cache = Mage::app()->getCache();
        $cacheKey = 'category_products_' .  Mage::app()->getStore()->getId() . '_' . $this->getCategoryId() . '_' . date('d-m-Y');
        $cachedProductCollection = $cache->load($cacheKey);

        if (!$cachedProductCollection) {
            $loadedProductCollection = parent::getLoadedProductCollection();
            $cachedProductCollection = serialize($loadedProductCollection->exportToArray());
            $cache->save($cachedProductCollection, $cacheKey, array('ProjectName'), 3600);
        } else {
            $loadedProductCollection = Mage::getModel('catalog/product')->getResourceCollection();
            $loadedProductCollection->setIsLoaded(true);
            $cachedProductCollectionArray = unserialize($cachedProductCollection);   
            $loadedProductCollection->importFromArray($cachedProductCollectionArray);
        }

        return $loadedProductCollection;
    }
}

代码可能会更紧凑一些,但是这样更容易理解.它旨在代替getLoadedProductCollection进行调用,以例如在一个页面中促进来自多个类别的产品.希望对您有帮助!

The code could be a bit more compact but like this a bit easier to understand. This is intended to be called instead of getLoadedProductCollection, to facilitate for product from multiple categoties in one page for example. Hope it helps!

这篇关于Magento:缓存集合上的序列化错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆