保卫萝卜3工厂关卡 工厂第22关怎么通关呢

保卫萝卜 3

研江创业 研江创业
回答
  • 丽子 丽子

    magento是基于zend framework的,所以cache的使用基本也继承了他的一些特性。我们要知道缓存中有几个重要的概念:
    数据本身;数据的标识;缓存生命期;缓存操作接口;zend_cache 的使用比较简单,它可以把数据保存到 file,memcache,sqlite 等介质(称为后端,backend)中.还有前端(frontend),主要用来对要缓存的数据进行转换,如序列化.
    zend framework 后端主要有
    apc(zend_cache_backend_apc),
    files(zend_cache_backend_file),
    memcached(zend_cache_backend_memcached)
    and some more.
    magento 增加了几种:
    database(varien_cache_backend_database)
    eaccelarator(varien_cache_backend_eaccelarator).
    为了更深入的理解magento cache,本文就以缓存某个block为例,分析下他的工作流程和原理。在magento中,所有的block都是继承自mage_core_block_abstract,当输出某个block到页面时,会调用到这个类的tohtml方法,该方法中有如下code片段:
    [php]view plaincopyhtml =$th**->_loadcache();加载缓存,假设为第一次加载,还没有被缓存过,进入if代码段
    if($html === false){
    translate=mage:getsingleton('core/translate');var$translate mage_core_model_translate*/
    if($th**->hasdata('translate_inline')){
    >settranslateinline($th**->getdata('translate_inline'));}
    th**->_beforetohtml();html =$th**->_tohtml();th**->_s**ecache($html);这句代码很简单,但却在内部完成了大量的工作,下面进入它内部深入分析
    if($th**->hasdata('translate_inline')){
    >settranslateinline(true);}
    }
    继续看本类中的function_s**ecache($data)
    [php]view plaincopy
    function_s**ecache($data)
    s**e block content to cache storage
    param string$data
    return mage_core_block_abstract
    protected function_s**ecache($data)
    {
    if(**_**($th**->getcachelifetime())|!mage:app()->usecache(self:cache_group)){
    return false;}
    cachekey=$th**->getcachekey();var$session mage_core_model_session*/
    session=mage:getsingleton('core/session');data=str_replace
    session->getsessionidqueryparam().'='.$session->getencryptedsessionid(),
    th**->_getsidplaceholder($cachekey),
    data
    可以肯定进入了mage_core_model_app 的function s**ecache
    mage:app()->s**ecache($data,$cachekey,$th**->getcachetags(),$th**->getcachelifetime());return$th**;}
    打开mage_core_model_app 的function s**ecache
    [php]view plaincopy
    s**ing cache data
    param mixed$data
    param string$id
    param array$tags
    return mage_core_model_app
    public function s**ecache($data,$id,$tags=array(),$lifetime=false)
    {
    th**->_cache->s**e($data,$id,$tags,$lifetime);return$th**;}
    可以看到$th**->_cache这个对象调用了s**e,继续看$th**->_cache到底属于哪个类的实例,在本类中找到protected function_initcache(),code如下:
    [php]view plaincopy
    initialize application cache instance
    return mage_core_model_app
    protected function_initcache()
    {
    th**->_**cachelocked=true;options=$th**->_config->getnode('global/cache');if($options){
    options=$options->asarray();} else {
    options=array();}
    实例化mage_core_model_cache,并传入参数$options
    th**->_cache=mage:getmodel('core/cache',$options);th**->_**cachelocked=false;return$th**;}
    上面mage:getmodel('core/cache',$options)的$options是app/etc/local.xml中节点global/cache下的配置,假设ocal.xml如下:
    [html]view plaincopy
    apc
    file
    1
    myshop_
    10
    能看到$th**->_cache是实例化了实例化mage_core_model_cache,所以mage_core_model_app 中的$th**->_cache->s**e($data,$id,$tags,$lifetime)即调用的mage_core_model_cache的function s**e。进入mage_core_model_cache的s**e:
    [php]view plaincopy
    s**e data
    param string$data
    param string$id
    param array$tags
    param int$lifetime
    return bool
    public function s**e($data,$id,$tags=array(),$lifetime=**)
    {
    add global magento cache tag to all cached data exclude config cache
    if!in_array(mage_core_model_config:cache_tag,$tags)){
    tags[]=mage_core_model_app:cache_tag;}
    return$th**->_frontend->s**e((string)$data,$th**->_id($id),$th**->_tags($tags),$lifetime);}
    可以看到$th**->_frontend->s**e(.)这句,那么这里的_frontend是什么呢?继续看此类的构造函数(只列出部分code):
    [php]view plaincopy
    backend=$th**->_getbackendoptions($options);frontend=$th**->_getfrontendoptions($options);th**->_frontend=zend_cache:factory('varien_cache_core',$backend['type'],$frontend,$backend['options'],true,true,true);没错_frontend就是类varien_cache_core的一个实例,因为varien_cache_core是继承自zend_cache_core,所以这里_frontend实际上实例化的是zend_cache_core,即调用的是zend_cache_core的s**e,再继续分析,打开zend_cache_core,找到function s**e它里面包含了如下代码片段:
    [php]view plaincopy
    if(($th**->_extendedbackend)&($th**->_backendcapabilities['priority'])){
    result=$th**->_backend->s**e($data,$id,$tags,$specificlifetime,$priority);} else {
    result=$th**->_backend->s**e($data,$id,$tags,$specificlifetime);}
    可以看到这里实际上又变成了_backend的来调用的s**e,(开头我们已经说了backend是用来保存数据的),那么这里_backend到底是哪个backend(file,db,apc.)呢?继续分析,在这个类里面有一个方法setbackend:
    [php]view plaincopy
    set the backend
    param zend_cache_backend$backendobject
    throws zend_cache_exception
    return void
    public function setbackend(zend_cache_backend$backendobject)
    {
    th**->_backend=$backendobject;some options(l**ted in$_directivesl**t)h**e to be given
    to the backend too(even if they are not"backend specific")
    directives=array();foreach(zend_cache_core:$_directivesl**t as$directive){
    directives[$directive]=$th**->_options[$directive];}
    th**->_backend->setdirectives($directives);if(in_array('zend_cache_backend_extendedinterface',class_implements($th**->_backend))){
    th**->_extendedbackend=true;th**->_backendcapabilities=$th**->_backend->getcapabilities();}
    }
    里面有$th**->_backend=$backendobject这句,$backendobject是传入的参数,那么是何时调用的setbackend呢?实际上,这个方法是在上边mage_core_model_cache里的s**e方法中调用$th**->_frontend=zend_cache:factory('varien_cache_core',$backend['type'],$frontend,$backend['options'],true,true,true);这句的的时候,已经被调用了,可以打开zend_cache的factory 方法查看,会发现有一句$frontendobject->setbackend($backendobject);参数$backendobject是factory传入的参数$backend['type'],$backend['type']到底是什么呢,我们在mage_core_model_cache的构造函数中看到$backend=$th**->_getbackendoptions($options)这句,所以$backend是在本类的_getbackendoptions中被设置的,找到_getbackendoptions,code如下:
    [php]view plaincopy
    get cache backend options.result array contain backend type('type' key)and backend options('options')
    param array$cacheoptions
    return array
    protected function_getbackendoptions(array$cacheoptions)
    {
    enable2levels=false;type=**set($cacheoptions['backend'])?cacheoptions['backend']:$th**->_defaultbackend;if(**set($cacheoptions['backend_options'])&**_array($cacheoptions['backend_options'])){
    options=$cacheoptions['backend_options'];} else {
    options=array();}
    backendtype=false;switch(strtolower($type)){
    case 'sqlite':
    if(extension_loaded('sqlite')&**set($options['cache_db_complete_path'])){
    backendtype='sqlite';}
    break;case 'memcached':
    if(extension_loaded('memcache')){
    if(**set($cacheoptions['memcached'])){
    options=$cacheoptions['memcached'];}
    enable2levels=true;backendtype='memcached';}
    break;case 'apc':
    if(extension_loaded('apc')&ini_get('apc.enabled')){
    enable2levels=true;backendtype='apc';}
    break;case 'xcache':
    if(extension_loaded('xcache')){
    enable2levels=true;backendtype='xcache';}
    break;case 'eaccelerator':
    case 'varien_cache_backend_eaccelerator':
    if(extension_loaded('eaccelerator')&ini_get('eaccelerator.enable')){
    enable2levels=true;backendtype='varien_cache_backend_eaccelerator';}
    break;case 'database':
    backendtype='varien_cache_backend_database';options=$th**->getdbadapteroptions();break;default:
    if($type!th**->_defaultbackend){
    try {
    if(class_ex**ts($type,true)){
    implements=class_implements($type,true);if(in_array('zend_cache_backend_interface',$implements)){
    backendtype=$type;}
    }
    } catch(exception$e){
    }
    }
    }
    if!backendtype){
    backendtype=$th**->_defaultbackend;foreach($th**->_defaultbackendoptions as$option=>$value){
    if!array_key_ex**ts($option,$options)){
    options[$option]=$value;}
    }
    }
    backendoptions=array('type'=>$backendtype,'options'=>$options);if($enable2levels){
    backendoptions=$th**->_gettwolevel**ackendoptions($backendoptions,$cacheoptions);}
    return$backendoptions;}
    代码有些长,但这个方法很重要,后端具体使用什么类型存储缓存都是在这里被设置和转换的,有代码分析可知,默认的backend为file,其他有sqlite,apc,memcached,xcache,eaccelerator,database等几种类型,当backend是memcached,apc,xcache时,magento就自动开启two level cache,具体设置可以自行看function_gettwolevel**ackendoptions。

类似问答
精品推荐

友情链接

友链互换QQ:

谷财 备案编号:蜀ICP备11019336号-3商务合作:235-677-2621

Copyright 2009-2020 Chengdu Sanzilewan Technology Co.,Ltd all rights reserve

抵制不良游戏 拒绝盗版游戏 注意自我保护 谨防受骗上当 适度游戏益脑 沉迷游戏伤身 合理安排时间 享受健康生活