自定义模块缓存自定义Block失效,代码是否存在问题?
你的Magento自定义Block缓存失效问题分析与修复
嘿,我帮你排查下这段缓存代码里的问题,这几个点是导致缓存不生效或者异常的关键:
1. 直接序列化集合对象是大坑
你现在直接把$collection序列化后存进缓存,但Magento的产品集合是包含数据库连接、资源模型这些没法被正确序列化的对象的。反序列化的时候要么直接报错,要么就算成功了,集合的状态也不对,根本没法正常调用它的方法或者获取数据——这大概率是你觉得缓存没生效的核心原因。
正确的做法是提取集合里的纯数据,比如用$collection->getData()把产品数据转成纯数组,缓存这个数组就没问题了,纯数组序列化反序列化完全正常。
2. 缓存保存时缺少标签和过期时间
Mage::app()->getCache()->save()方法你只传了两个参数,但其实需要加上缓存标签和过期时间:
- 缓存标签:用来关联相关的实体(比如产品、分类),这样当后台更新产品/分类时,Magento会自动清理带对应标签的缓存,避免用户看到旧数据。
- 过期时间:设置缓存的有效期,比如86400秒(1天),防止缓存永久存在。
3. 冗余的缓存加载操作
你在保存缓存后又调用Mage::app()->getCache()->load($cacheId)返回,这完全没必要,直接返回你刚处理好的数据就行,既浪费性能又多此一举。
另外,建议把当前店铺ID加到缓存ID里,多店铺场景下能避免不同店铺的缓存混乱。
修复后的代码示例
$cacheId = 'my_cache_id_' . Mage::app()->getStore()->getId(); // 加上店铺ID区分多店铺缓存 $cacheTags = [ Mage_Catalog_Model_Product::CACHE_TAG, Mage_Catalog_Model_Category::CACHE_TAG ]; $cacheLifetime = 86400; // 缓存1天,可根据需求调整 if (false !== ($data = Mage::app()->getCache()->load($cacheId))) { $data = unserialize($data); return $data; } else { $collection = Mage::getModel('catalog/product')->getCollection() ->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) ->addFieldToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED) ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes()) ->addMinimalPrice() ->addTaxPercents() ->addStoreFilter() ->addAttributeToSort('entity_id', 'desc'); // 应用分类过滤 $collection = $this->categoryFilter($collection); // 设置产品数量限制 $collection->setPageSize($this->getWidgetCfg('limit')); // 提取集合的纯数据,而非序列化集合对象 $productData = $collection->getData(); // 保存缓存,带上标签和过期时间 Mage::app()->getCache()->save(serialize($productData), $cacheId, $cacheTags, $cacheLifetime); // 直接返回数据即可 return $productData; }
额外说明
如果你的Block需要渲染产品信息,拿到$productData数组后,可以遍历它,用Mage::getModel('catalog/product')->load($item['entity_id'])加载产品模型(如果想更高效,可以提前在集合里加载好所有需要的属性,直接用数组里的字段渲染就行,不用再加载模型)。
内容的提问来源于stack exchange,提问作者Info E
相关产品推荐
相关产品推荐

