我们想在产品页面添加动态块.问题是产品页面具有完整页面缓存(由于速度问题,我们无法将其关闭).我们希望根据登录用户的帐户在每个产品页面上显示不同的信息,并且因产品而异.
我创建了一个具有自己的缓存的单独块,但是它显示了上一个产品页面中的相同块.我正在尝试更改它的缓存方法,因此它不会保存以前产品页面中的缓存.
它最初几次进入产品页面,然后突然开始显示一个Magento错误页面,上面写着:"网站在检索http://www.mycompany.com/productpage.html时遇到错误.它可能是关闭维护或配置不正确."
这是我到目前为止所做的.我创建了app/code/local/MyCompany/MyModule/PageCache/etc/config.xml来添加MyCompany_PageCache_Model.
然后我用这些函数在app/code/local/MyCompany/MyModule/PageCache/Model/Container/MyFile.php中创建了控制缓存的文件:
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();
}
Run Code Online (Sandbox Code Playgroud)
我还使用我的占位符为CONSTANT_CACHE在Catalog/etc下创建了cache.xml.
上面的语法是不正确的,还是有更简单的方法来做到这一点?
Vin*_*nai 124
为了回答我需要先解释一下.Magento FPC流程知道四种状态.
在没有初始化完整Magento应用程序的情况下处理状态1和2.状态3和4要求初始化应用程序并处理路由.出于这个原因,如果可能的话,目的是服务于州1和2的请求,否则你将失去FPC可能改进的很大一部分.
从开发人员的角度来看,状态1很无聊,无所事事,所以让我们继续......
在状态2中,页面包含动态块.目前,Magento尚未完全初始化.
FPC处理器加载缓存页面并在其中查找动态块的占位符.
通过分析占位符,处理器能够识别动态块的容器类,实例化它并调用applyWithoutApp($content)它.(该方法的名称是指到目前为止尚未初始化Magento应用程序的事实).然后容器尝试使用方法返回的缓存键从块缓存加载动态块内容$this->_getCacheId().
如果返回缓存键并且可以加载缓存条目,则容器类将$content使用缓存的块输出替换占位符,并完成FPC.
到目前为止,没有产生太多的开销.
因此,applyWithoutApp($content)在状态2中无法获取和传递动态块内容,因此即使在FPC中找到了页面的其余部分,也需要生成块内容.
为此,FPC模块将请求设置为pagecache/request/process,并遵循常规Magento应用程序初始化和路由.
这意味着使用状态2产生了更多的开销,即使它仍然比没有FPC的常规页面加载好一点,因为例如跳过URL重写.
最后,前端控制器和标准路由器将请求委托给该RequestController::processAction()方法.
该方法为动态块提取先前实例化的容器类,并对其进行调用applyInApp($content).
此方法运行$this->_renderBlock()以实例化实际块类并返回其输出.您已根据自己的问题实施了此方法.FPC现在可以用块内容替换占位符并传递页面.
需要注意的一点是,这不是常规的产品详细信息页面请求,因此例如Mage::registry('current_product')不可用!根据您的块实现,这可能会影响块级缓存或动态块的内容生成.我怀疑这可能是你的问题源于何处,但我会进一步解决可能的解决方法.
在这种状态下,FPC没有找到所请求页面的缓存记录,因此Magento像往常一样生成页面,例如,产品详细信息页面输出由Mage_Catalog_ProductController::viewAction().
根据所有配置为动态的块cache.xml都包含在占位符标记中.
占位符标记包含参数,稍后将其传递给第2步和第3步的容器对象.始终设置的唯一参数是容器和块类名.但几乎总是a cache_id和a 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;
}
Run Code Online (Sandbox Code Playgroud)
现在可以使用容器类访问这些值$this->_placeholder->getAttribute('current_product_id').
您可能不希望_saveCache()在容器类中重写以返回false.而是将客户ID和产品ID包含在返回的字符串中_getCacheId().这样每个客户都可以获得自己的缓存条目.一些开销将减少,因为applyWithoutApp()可以从缓存中保存和加载动态块(如果一个页面被同一客户查看两次).
在_renderBlock()设置所需的附加值,以便块能够在其上生成它的内容,例如
$block->setProductId($this->_placeholder->getAttribute('current_product_id'));
Run Code Online (Sandbox Code Playgroud)
在块的方面,包括缓存信息数组中的产品ID和客户ID将确保每个客户获得所请求页面的正确输出,即使缓存块也是如此.
我无法确定,(你还没有提供块代码),但我怀疑你使用的缓存ID不包含将块的缓存记录唯一映射到正确产品所需的所有参数.
使用这些步骤并了解如何将参数传递给动态块容器,即使在创建自定义动态块时,也可以保留大部分FPC性能增益.我希望这些信息足以让您能够追踪您所描述的问题并进行修复.
通常,如果要个性化要存储在整页缓存中的页面,可以使用两种方法.
| 归档时间: |
|
| 查看次数: |
20346 次 |
| 最近记录: |