当我使用Zend_Cache缓存Zend_Navigation的页面层次结构时,我遇到了麻烦。
背景:我有大约50页,大约300个产品存储在数据库中。我查询数据库并创建一个数组以提供给Zend_Navigation。
缓存是
$secondsBetweenRefreshes = APPLICATION_ENV == 'development' ? 30 : 300;
self::$cache = Zend_Cache::factory( 'Core', 'File',
array( 'automatic_serialization' => true,
'lifetime' => $secondsBetweenRefreshes ),
array( 'cache_dir' => CACHE_PATH . 'nav/' )
);
这很好用
$struct = $cache->load('Zend_Navigation');
if (empty($struct))
{
$cache->save($struct = self::getSiteStructure() );
}
return new Zend_Navigation( $struct );
这会被打乱
$struct = $cache->load('Zend_Navigation');
if (empty($struct))
{
$cache->save($struct = new Zend_Navigation( self::getSiteStructure() );
}
return $struct;
如果未从缓存中提取导航,则导航正常。是的,显而易见的解决方案不是缓存Zend_Navigation,但构造函数在构建其内部表示方面做了大量工作:使用尽可能多的预先计算来进行缓存是有意义的......
我仍在尝试查看加扰结果中是否存在模式。树中没有循环/循环。
答案 0 :(得分:1)
在阅读完这个问题之后,我快速浏览了一下Zend_Navigation
代码,似乎不存在使用序列化缓存它的任何固有问题。但是,查看Zend_Navigation文档,我发现了以下内容:
toArray()方法将容器及其中的页面转换为数组。这对于序列化和调试很有用。 - Zend Navigation Containers: Other
您可能想要创建Zend_Navigation对象,使用toArray()函数来创建数组并缓存它。从阵列重新创建页面应该相当便宜,尽管您可能想要进行一些测试。
此外,如果可能,请向Zend Framework维护人员提交错误报告,以便他们可以查看它。
Zend_Navigation
虽然一个有趣的组件,可以说是一个有用的组件,但我并没有使用它。对于在内存中拥有10,000多个对象的大型网站并不是一个明智的想法,而Zend_Navigation
中某些项目的实现方式会使其变得缓慢而且难以处理。许多使用Zend Framework的开发人员已经找到了实现相同目标的其他方法。
答案 1 :(得分:1)
关于缓存页面数组的警告......
如果您从toArray()
缓存数组,并且只想使用setPages($pagesFromCache)
,则需要停用缓存数组中的所有页面以供将来使用。
小心,Zend_Navigation_Page_Mvc::isActive()
检查当前请求。这意味着您当前的MVC页面的isActive()
仍会返回true ,即使您拨打了setActive(false)
。
我发现停用所有页面的唯一方法是递归遍历生成的数组:
$pages = $navigation->toArray();
array_walk_recursive(
$pages,
function(&$item, $key)
{
if($key === 'active')
$item = false;
}
);
$cache->save($pages, 'pages');
答案 2 :(得分:0)
谢谢你的帖子;我认为可能存在组合Zend_Navigation和Zend_Cache的问题,但我已经能够在普通的 Zend_Navigation 对象上使用 save 方法,然后从缓存中检索对象无需使用 toArray()。
X-Istence:我同意随着导航物体的大小增长,它可能会变得相当笨拙;虽然我不得不深入挖掘代码,以完成我对大小临界点的理解。