Magento的:在缓存集合序列化错误(Magento: serialization error o

2019-10-23 14:37发布

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

$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;

每一个从这个类扩展子类都将使用同一个集合在同一个运行栈。 我想保存在缓存中这个集合(你可以看到在看代码),这样以来,第二次的子类将使用它,该脚本将不需要重新加载它。

问题是,这是不可能使用缓存,因为缓存需要一个序列化的集合,在这种情况下,由于收集含有不能被序列化的Mage_Core_Model_Config_Element我不能做到这一点(它触发著名的错误““Mage_Core_Model_Config_Element系列化' 不被允许”)。

我想尽了各种办法,甚至json_encode / json_decode,而不是序列化/反序列化,但我解决不了的问题。

你有一些解决方案? 谢谢!

Answer 1:

这可能有点迟,但希望能有人提出在未来正确的轨道上。

当你发现,你不能序列集合,但你可以得到返回的项目作为一个数组和缓存的。 这是步骤1。

然后,这取决于你如何使用集合(例如在产品清单)和count()被调用时,Magento的将尝试再次装入收集,从而导致错误,因为IsLoaded标志是假的,但你将有项目。

为了解决这个问题,你需要添加项目到集合后设置的标志。 为了做到这一点,你应该重写产品资源集合(以访问这个标志)。 所以codewise:

该代码是基于你要使用的产品列表页面上的集合,并且不支持排序/过滤等,因为只有项目被缓存的假设。

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

<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步:创建资源类

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

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

<?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,以促进产品从多个categoties在一个页面的例子。 希望能帮助到你!



Answer 2:

Magento的有它的内置集合缓存,但请记住,收集缓存并不缓存集合对象,它从数据库基本负荷的SQL缓存中的数据执行。

你的情况,你可以试试下面的代码:

        $_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);                                                                       

       if (Mage::app()->useCache('collections')) {
            $_productCollection->initCache(
               Mage::app()->getCache(),
               "defineuniquevalue",
               array("COLLECTION_DATA")
         );
     }
 return $_productCollection;


文章来源: Magento: serialization error on caching Collection