【问题标题】:Magento 1.9 Block Cache - prevent form key caching on Mage Catalog Block Product ViewMagento 1.9 块缓存 - 防止在 Mage Catalog 块产品视图上缓存表单键
【发布时间】:2014-09-27 09:36:23
【问题描述】:

您好 Magento 专业人士,

我使用 Magento 块缓存机制来提高产品页面的性能。 它在 Magento CE 1.6.2 上运行良好,但现在我升级到 CE 1.9.0.1 并且块缓存不适用于 Magento 新表单键。

产品页面仍在缓存中,但它们自然会被缓存,包括表单操作中的新表单键。当另一个用户尝试将产品添加到购物车时,它将不起作用,因为其他用户的表单键已被缓存。 因此,没有添加任何产品,购物车保持为空。

有没有办法将表单键注入缓存代码或其他缓存产品页面的方法?

我扩展的 Mage_Catalog_Block_Product_View 中的缓存方法如下所示

protected function _construct()
{
        $this->addData(array(
            'cache_tags'        => array(Mage_Catalog_Model_Product::CACHE_TAG . "_" . $this->getProduct()->getId()),
        ));
}

public function getCacheKey()
{
    if (!$this->hasData('cache_key')) {
        //$cacheKey = LAYOUTNAME_STORE+ID_PRODUCT+ID
        $cacheKey = $this->getNameInLayout().'_STORE'.Mage::app()->getStore()->getId().'_PRODUCT'.$this->getProduct()->getId();         
        $this->setCacheKey($cacheKey);
    }
    return $this->getData('cache_key');
}

public function getCacheLifetime()
{     
      if($this->getNameInLayout()!='product.info') return null;
      if(!$this->cacheEnabled()) return null;         
      return 9999999999;
}

public static function cacheEnabled() {
    return true;
}   

【问题讨论】:

    标签: forms magento block magento-1.6 magento-1.9


    【解决方案1】:

    我认为我已经构建了一个更好的修复程序。 我一次修复了整个 HTML 输出,还修复了隐藏表单输入中的 form_key 字段。

    我的分机监听事件controller_front_send_response_before。方法是controllerFrontSendResponseBefore in app/code/community/JeroenVermeulen/BlockCache/Model/Observer.php

    https://github.com/jeroenvermeulen/jeroenvermeulen-blockcache/

    最好使用事件而不是覆盖,因为您不会冒 2 个扩展覆盖相同核心功能的风险。在 Magento 升级后,事件也更有可能发挥作用。

    【讨论】:

    • 注意:Magento 还有一个专门的 Stack Exchange:magento.stackexchange.com
    • 嘿 Jeroen,我同意挂钩事件通常比覆盖类更好,但我不确定您的解决方案是否真的更适合这种情况。在我的情况下,我真的必须重写该类,因为我需要重写缓存方法。如果另一个扩展将覆盖同一个类,我将不得不合并它们......我知道这一点。但是此刻,在我看来,您的解决方案就像用大锤敲碎坚果。我只遇到了这个块的问题,因为我正在使用缓存。您需要在哪里替换 form_keys?真的需要编辑整个回复吗?
    • 使用事件而不是覆盖越来越流行,因为它可以防止扩展之间的冲突。因为我很早就使用了轻量级的 'is_a()' 语句,所以块观察者不是很重。因为我从缓存中提取了类别和产品详细信息页面的全部内容,所以需要在内容中替换表单键,否则“添加到购物车”按钮在 Magento > 1.8 中不起作用
    • 你能告诉我你对'is_a()'语句的意思吗?像'instanceof'这样的东西?它是 Magento 函数吗?
    • 你是对的,它类似于instanceofMore info: PHP Manual。几周前我 discovered instanceof 快 2 倍,所以我在我的扩展程序中改用 instanceof
    【解决方案2】:

    我现在找到了一个快速修复,但仍在寻找更好的解决方案。 现在,我在扩展块中添加了 _afterToHtml($html) 方法,并在从缓存返回 html 之前注入了 form_key。 如果其他人需要此快速修复,请确保 if 条件正确。它确保这仅在我真正缓存的块中完成,而不是在其他产品视图块中完成。

    这是我目前的快速修复:

    public function _afterToHtml($html) {
        if($this->getNameInLayout() == 'product.info') {
            $formkey = Mage::getSingleton('core/session')->getFormKey();
            $formkey = "/form_key/".$formkey."/";        
            $html = preg_replace("/\/form_key\/[a-zA-Z0-9,.-]+\//", $formkey, $html); 
        }  
        return parent::_afterToHtml($html);
    }
    

    我正在考虑将来切换到全页缓存,但解决这个问题会很好,因为配置另一种缓存方法也需要很多时间。

    因此,如果您有比这个肮脏的快速修复更好的主意,请提供帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-27
      • 2015-04-10
      • 1970-01-01
      • 2012-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多