gpt4 book ai didi

caching - 如何在打开全页缓存的产品页面中包含动态 block ?

转载 作者:行者123 更新时间:2023-12-03 02:00:27 24 4
gpt4 key购买 nike

我们想向产品页面添加一个动态块。问题是产品页面有整页缓存(由于速度问题,我们无法关闭它)。我们希望根据登录用户的帐户在每个产品页面上显示不同的信息,并且因产品而异。

我创建了一个单独的块,它有自己的缓存,但这显示了与上一个产品页面相同的块。我正在尝试更改它的缓存方法,因此它不会保存上一个产品页面的缓存。

它在我转到产品页面的前几次工作时,突然开始显示 Magento 错误页面,上面写着“网站在检索 http://www.mycompany.com/productpage.html 时遇到错误。
它可能因维护而停机或配置不正确。”

这是我到目前为止所做的。

I created app/code/local/MyCompany/MyModule/PageCache/etc/config.xml to add MyCompany_PageCache_Model.

Then I created the file that controls caching in app/code/local/MyCompany/MyModule/PageCache/Model/Container/MyFile.php
with these functions:


protected function _getCacheId()
{
return 'CONSTANT_CACHE' . md5($this->_placeholder->getAttribute('cache_id'));
}

protected function _saveCache($data, $id, $tags = array(), $lifetime = null)
{
return false;
}

protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');

$block = new $blockClass;
$block->setTemplate($template);
$block->setLayout(Mage::app()->getLayout());
return $block->toHtml();
}

我还创建了 cache.xml 目录/等 与我的占位符 CONSTANT_CACHE。

上面的语法是错误的,还是有更简单的方法来做到这一点?

最佳答案

概述

为了回答我需要先解释一下。 Magento FPC 进程知道四种状态。

  • 缓存中的页面,无动态块
  • 缓存页面,缓存动态块
  • 缓存中的页面,未缓存动态块
  • 页面不在缓存中

  • 状态 1 和 2 的处理没有初始化完整的 Magento 应用程序。状态 3 和 4 要求初始化应用程序并处理路由。出于这个原因,如果可能的话,旨在满足来自状态 1 和 2 的请求,否则您将失去 FPC 可能改进的很大一部分。

    状态 1

    从开发人员的角度来看,状态 1 很无聊,无事可做,所以让我们继续......

    状态 2

    在状态 2 中,页面包含动态块。 现在,Magento 还没有完全初始化 .
    FPC 处理器加载一个缓存页面并在其中找到一个动态块的占位符。
    通过分析占位符,处理器能够识别动态块的容器类,实例化它,并调用 applyWithoutApp($content)在上面。 (该方法的名称是指到目前为止 Magento 应用程序尚未初始化的事实)。
    然后容器尝试使用方法 $this->_getCacheId() 返回的缓存键从块缓存加载动态块内容。 .
    如果返回缓存键并且可以加载缓存条目,则容器类将替换 $content 中的占位符。使用缓存的块输出和 FPC 完成。
    到目前为止,还没有产生多少开销。

    状态 3

    所以 applyWithoutApp($content)在状态 2 中无法获取和传递动态块内容,因此需要生成块内容,即使页面的其余部分已在 FPC 中找到。
    为此,FPC 模块将请求设置为 pagecache/request/process ,并遵循常规的 Magento 应用程序初始化和路由。
    这意味着比状态 2 产生更多的开销,即使它仍然比没有 FPC 的常规页面加载要好一些,因为例如跳过 URL 重写。
    最后,前端 Controller 和标准路由器将请求委托(delegate)给 RequestController::processAction()方法。
    该方法为动态块获取先前实例化的容器类,并调用 applyInApp($content)在上面。
    此方法运行 $this->_renderBlock()实例化真正的块类并返回它的输出。您已经根据您的问题实现了此方法。 FPC 现在可以用块内容替换占位符并交付页面。
    需要注意的一件事是这不是常规的产品详细信息页面请求,因此例如 Mage::registry('current_product')不可用!
    根据您的块实现,这可能会影响动态块的块级缓存或内容生成。我怀疑这可能是您的问题的根源,但我会在更进一步的地方找到可能的解决方法。

    状态 4

    在这种状态下,FPC 没有找到请求页面的缓存记录,因此 Magento 像往常一样生成页面,例如产品详细信息页面输出由 Mage_Catalog_ProductController::viewAction() 创建.
    根据 cache.xml 配置为动态的所有块, 被包裹在占位符标签中。
    占位符标签包含参数,稍后将这些参数传递给第 2 步和第 3 步的容器对象。唯一始终设置的参数是容器和块类名称。但几乎总是一个 cache_id和一个 template也设置好了。
    在容器类中,可以使用 $this->_placeholder->getAttribute('cache_id') 访问这些值。 (就像您在容器的 _getCacheId() 方法中所做的那样)。

    即使您掩盖了这个冗长答案的大部分内容,这也是您可能会感兴趣的地方。如果您需要其他值来生成块缓存 ID 或块输出(例如产品 ID 或客户 ID), 您可以将这些设置为占位符的参数 .

    为此,您需要在块 getCacheKeyInfo() 返回的数组上设置它们。带有 的方法字符串作为数组键 .如果您使用数字数组索引,它们将不会被设置为占位符上的参数。
    public function getCacheKeyInfo() {
    $info = parent::getCacheKeyInfo();
    $info['current_product_id'] = Mage::registry('current_product')->getId();
    $info['customer_id'] = Mage::getSingleton('customer/session')->getCustomerId();
    return $info;
    }

    现在可以使用 $this->_placeholder->getAttribute('current_product_id') 在容器类中访问这些值。 .

    结论

    您可能不想覆盖 _saveCache()在您的容器类中返回 false .相反,在 _getCacheId() 返回的字符串中包含客户 ID 和产品 ID。 .这样每个客户都会获得自己的缓存条目。因为 applyWithoutApp() 会减少一些开销可以从缓存中保存和加载动态块(如果一个页面被同一个客户浏览了两次)。

    _renderBlock()设置您需要的附加值,以便块能够在其上生成其内容,例如
    $block->setProductId($this->_placeholder->getAttribute('current_product_id'));

    在块方面,在缓存信息数组中包含产品 id 和客户 id 将确保每个客户获得请求页面的正确输出,即使块被缓存。

    我不能确定,(您还没有提供块代码),但我怀疑您使用的缓存 ID 不包含将块的缓存记录唯一映射到正确产品所需的所有参数.

    使用这些步骤并了解如何将参数传递给动态块容器,即使在创建自定义动态块时,也可以保留大部分 FPC 性能增益。我希望这些信息足以让您能够追踪您所描述的问题并修复它。

    关于caching - 如何在打开全页缓存的产品页面中包含动态 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9120413/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com