问保卫萝卜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。
-
问 保卫萝卜3工厂第38关怎么布阵 工厂38关金萝卜通关攻略
提问时间:2024-05-06 10:31:12
答 保卫萝卜3工厂第38关金萝卜通关攻略:可用炮塔:毒气桶、魔法球、风扇、汽油瓶怪物波数:18波怪物等级:lv16初始萝卜币:1500障碍物:25
-
问 保卫萝卜3工厂第28关金萝卜攻略 工厂28关怎么过
提问时间:2024-05-06 08:25:52
答 可建造炮塔:汽油瓶、魔法球、太阳花;本关比较正常,难度不高,障碍物清理好就好了,到了后期觉得输出乏力了的话配合上魔法球也会有很好的效果。保卫萝卜3工厂第28关攻...
-
问 保卫萝卜3工厂第37关怎么过 工厂第37关金萝卜通关攻略
提问时间:2024-05-06 05:54:16
答 本关还是有点难度的,初始资金较少,如果能合理用好5个滑竿,还是可以很轻松渡过弱势的前期哦。开局,先造一个满级的毒气桶渡过前期,剩下的萝卜币建议放一个2级风扇在左...
-
问 保卫萝卜3工厂第26关怎么过 工厂第26关金萝卜通关攻略
提问时间:2024-05-06 03:21:13
答 可建造炮塔:冰冻星星、魔法球、太阳花。1、太阳花可以有效的抵挡前期的敌人和破坏障碍物,尽快升级。2、前期尽快处理好障碍物才行。3、中间的障碍物破坏了之后记得补充...
-
问 保卫萝卜3工厂第17关金萝卜攻略 工厂17关怎么过
提问时间:2024-05-06 18:33:07
答 关卡介绍:工厂模式第17关,怪物波次19波,怪物等级8级,提供炮台:汽油瓶、冰冻星、太阳花。好友助战:关卡的开始之前大家是可以选择好友助战的,选择自己的好友助战...
-
问 保卫萝卜3工厂第39关怎么通关 工厂第39关金萝卜通关技巧推荐
提问时间:2024-05-06 21:08:24
答 可用炮塔:火箭、毒气桶、雷达怪物波数:16波怪物等级:lv16初始萝卜币:500障碍物:26本关初始资金只有500,而且没有减速炮塔,但上来会送两个毒气桶,上来
-
问 保卫萝卜3工厂关卡第31关怎么过
提问时间:2024-05-06 21:20:14
答 开局先把中间的太阳花升满,并在滑道两侧各放上一个太阳花并把他们升满,注意要把他们拉倒两侧的顶端哦,这样就可以边清怪边拆障碍物了。周围的障碍物清完之后,可以获得3...
-
问 保卫萝卜3工厂关卡第23关怎么过
提问时间:2024-05-06 06:47:03
答 保卫萝卜2第22关攻略 森林22宝石金萝卜教程【额外任务】1、使用太阳花消灭120个怪物。2、成功建造4个火箭塔(顶级)。3、在99秒内消除3个风车。额外任务,...
-
问 保卫萝卜3工厂19金萝卜怎么通关
提问时间:2024-05-06 05:32:22
答 保卫萝卜3工厂19金萝卜怎么通关工厂19图文过关,在保卫萝卜3手游中工厂19怎么通关咧,小编向大家介绍下工厂19的通关技巧,希望对大家有所帮助。首选一开场四个角...
-
问 保卫萝卜3工厂15关怎么过 工厂15关攻略
提问时间:2024-05-06 20:45:17
答 工厂第15关是boss关卡,共有21波怪物。保卫萝卜3工厂第15关攻略http://news.4399.com/bwlb3/guanka/gc/m/64166