【问题标题】:ZF - How to cache parts of the layoutZF - 如何缓存部分布局
【发布时间】:2010-08-16 14:07:13
【问题描述】:

我使用 Stacic Page Cache(带有缓存操作助手)来缓存我的应用程序的大部分页面。
这非常快,但并不总是合适的。

  • 如何缓存包含动态数据的页面?例如。布局包含特定于用户的信息。

我考虑的一种解决方案是通过 Ajax 加载额外的数据。 但在我的情况下,最好缓存部分页面(例如条目列表或侧边栏部分)。

  • 有没有 ZF 推荐的方法?例如。只缓存视图,不缓存布局,反之亦然。

缓存动作助手提供了很好的接口来缓存所有动作。任何缓存页面内容或部分内容或查看帮助程序的解决方案?

【问题讨论】:

    标签: performance zend-framework caching


    【解决方案1】:

    我最近一直在做的是创建服务,然后使用数据库连接和缓存对象配置该服务。检索数据使用一种“延迟加载级联”,首先在内存中查找,然后在缓存中,然后到数据库。

    例如,我的一个应用程序适用于在我国多个(但不是全部)省份开展业务的房地产代理机构。我们有一个省份的数据库表,其中一些为前端启用,我们需要在不同的地方呈现它们(例如,作为选择元素中的选项)。我们做这样的事情(我正在使用的遗留代码库使用 DAO 对象进行数据库访问,使用 PEAR 的 Cache_Lite 进行缓存,因此该示例并非严格意义上的 Zend 框架,但原理同样适用):

    /**
     * A service for fetching provinces
     */
    class My_Service_Provinces
    {
        protected $_daoProvinces;
        protected $_provinces = array();
        protected $_cache;
    
    
        public function __construct($daoProvinces)
        {
            $this->setDaoProvinces($daoProvinces);
        }
    
        public function setDaoProvinces($daoProvinces)
        {
            $this->_daoProvinces = $daoProvinces;
            return $this;
        }
    
        public function getDaoProvinces()
        {
            return $this->_daoProvinces;
        }
    
        public function setCache($cache)
        {
            $this->_cache = $cache;
            return $this;
        }
    
        public function getCache()
        {
            if (null == $this->_cache){
                $this->_cache = new My_Cache_Provinces();
            }
            return $this->_cache;
        }
    
        public function getProvinces()
        {
            if (null == $this->_provinces){
                $cache = $this->getCache();
                $data = $cache->get();
                if (!$data){
                    $dao = $this->getDaoProvinces();
                    $rows = $dao->frontend();
                    $data = array();
                    while ($row = $rows->get_row()){
                        $data[$row['provinceId']] = $row;
                    }
                    $cache->save(serialize($data));
                } else {
                    $data = unserialize($data);
                }
                $this->_provinces = $data;
            }
            return $this->_provinces;
        }
    
        public function getProvince($provinceId)
        {
            $provinces = $this->getProvinces();
            return isset($provinces[$provinceId]) ? $provinces[$provinceId] : null;
        }
    }
    

    缓存对象已预先配置了合适的生命周期。我为很少变化的数据赋予较长的生命周期,为频繁变化的数据赋予较短的生命周期。如果我真的需要对应用程序立即可用的数据更改 - 例如,管理员添加了一个新省 - 我实例化缓存对象并在更新时清除缓存。

    我什至添加了一个工厂来帮助实例化服务,这样调用代码就不必担心依赖关系。调用代码——可能在控制器中,甚至在视图或视图助手中——看起来像:

    $service = My_Service_Factory::getService('provinces');
    $provinces = $service->getProvinces();
    

    知道什么?

    【讨论】:

    • 谢谢。这有点明显。但是阅读您的帖子后,我想到了My_View_Helper_Cached_AbstractMy_Service_Abstract::setCache($cache, $lifetime)。你怎么看?那么如何在application.ini中设置缓存资源呢?
    • 是的,这很明显。 ;-) 对于与“核心”页面请求无关的内容——布局的东西,比如侧边栏——我喜欢你的视图助手方法。视图助手调用使用缓存的服务。您为缓存添加可配置生命周期的想法似乎非常好。但是缓存对象本身没有作为前端选项之一的生命周期“烘焙”吗?所以我看到了My_Service_Astract::setCacheLifetime($lifetime) 形式的方法签名。然后,特定的服务子类在惰性实例化缓存对象时可以使用不同的生命周期。
    • 实际上在大多数情况下$lifetime 将是无限的。更重要的参数是$cachetag,根据要求清除。
    猜你喜欢
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 2011-09-03
    • 2018-12-05
    • 1970-01-01
    • 2014-05-29
    相关资源
    最近更新 更多