`
coolsooner
  • 浏览: 1303030 次
文章分类
社区版块
存档分类
最新评论

2011-1-4-----核心模型---mage_core_model_cache---construct方法--个人分析

 
阅读更多

//construct.initialize内存实例 base on $options

/**

* Class constructor. Initialize cache instance based on options

*

* @param array $options

*/

public function __construct(array $options = array())

{

$this->_defaultBackendOptions['cache_dir'] = Mage::getBaseDir('cache');

/**

* Initialize id prefix

*/

$this->_idPrefix = isset($options['id_prefix']) ? $options['id_prefix'] : '';

if (!$this->_idPrefix && isset($options['prefix'])) {

$this->_idPrefix = $options['prefix'];

}

if (empty($this->_idPrefix)) {

$this->_idPrefix = substr(md5(Mage::getConfig()->getOptions()->getEtcDir()), 0, 3).'_';

}

$backend = $this->_getBackendOptions($options);

$frontend = $this->_getFrontendOptions($options);

$this->_frontend = Zend_Cache::factory('Varien_Cache_Core', $backend['type'], $frontend, $backend['options'],

true, true, true

);

if (isset($options['request_processors'])) {

$this->_requestProcessors = $options['request_processors'];

}

}

1

$this->_defaultBackendOptions['cache_dir'] = Mage::getBaseDir('cache');

为cache对象属性:_defaultBackendOptions['cache_dir']赋值为var/cache/.

2

//为$this->idPrefix赋值:

取决于$options里面的变量,如:id_prefix,prefix,顺序为:$options['id_prefix']存在,则$this->idPrefix = $options['id_prefix'].如果$options['prefix']存在,则$this->idPrefix = $options[id_prefix],

如果都不存在,下面有介绍。。。。

$this->_idPrefix = isset($options['id_prefix']) ? $options['id_prefix'] : '';

if (!$this->_idPrefix && isset($options['prefix'])) {

$this->_idPrefix = $options['prefix'];

}

if (empty($this->_idPrefix)) {

$this->_idPrefix = substr(md5(Mage::getConfig()->getOptions()->getEtcDir()), 0, 3).'_';

}

3

$backend = $this->_getBackendOptions($options);

//该函数的参数:$cacheOptions,即为construct中的$options参数。

protected function _getBackendOptions(array $cacheOptions)

{

$enable2levels = false;

//1

$type = isset($cacheOptions['backend']) ? $cacheOptions['backend'] : $this->_defaultBackend;

//2

if (isset($cacheOptions['backend_options']) && is_array($cacheOptions['backend_options'])) {

$options = $cacheOptions['backend_options'];

} else {

$options = array();

}

//

$backendType = false;

//3

switch (strtolower($type)) {

case 'sqlite':

if (extension_loaded('sqlite') && isset($options['cache_db_complete_path'])) {

$backendType = 'Sqlite';

}

break;

//4

case 'memcached':

if (extension_loaded('memcache')) {

if (isset($cacheOptions['memcached'])) {

$options = $cacheOptions['memcached'];

}

$enable2levels = true;

$backendType = 'Memcached';

}

break;

case 'apc':

//5

if (extension_loaded('apc') && ini_get('apc.enabled')) {

$enable2levels = true;

$backendType = 'Apc';

}

break;

//6

case 'xcache':

if (extension_loaded('xcache')) {

$enable2levels = true;

$backendType = 'Xcache';

}

break;

case 'eaccelerator':

//7

case 'varien_cache_backend_eaccelerator':

if (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) {

$enable2levels = true;

$backendType = 'Varien_Cache_Backend_Eaccelerator';

}

break;

//8

case 'database':

$backendType = 'Varien_Cache_Backend_Database';

$options = $this->getDbAdapterOptions();

break;

//9

default:

if ($type != $this->_defaultBackend) {

try {

if (class_exists($type, true)) {

$implements = class_implements($type, true);

if (in_array('Zend_Cache_Backend_Interface', $implements)) {

$backendType = $type;

}

}

} catch (Exception $e) {

}

}

}

//10

if (!$backendType) {

$backendType = $this->_defaultBackend;

foreach ($this->_defaultBackendOptions as $option => $value) {

if (!array_key_exists($option, $options)) {

$options[$option] = $value;

}

}

}

//11

$backendOptions = array('type' => $backendType, 'options' => $options);

if ($enable2levels) {

$backendOptions = $this->_getTwoLevelsBackendOptions($backendOptions, $cacheOptions);

}

return $backendOptions;

}

3.1

$type = isset($cacheOptions['backend']) ? $cacheOptions['backend'] : $this->_defaultBackend;

如果存在$cacheOptions['backend'],则$type等于$cacheOptions['backend'],如果不存在,则$type等于$this->_defaultBackend;

3.2

if (isset($cacheOptions['backend_options']) && is_array($cacheOptions['backend_options'])) {

$options = $cacheOptions['backend_options'];

} else {

$options = array();

}

如果$cacheOptions['backend_options']存在,而且是数组,则$options等于

$cacheOptions['backend_options']

3.3

switch (strtolower($type)) {

case 'sqlite':

if (extension_loaded('sqlite') && isset($options['cache_db_complete_path'])) {

$backendType = 'Sqlite';

}

break;

由3.1可以得出$type,如果

1>$type='sqlite',(sqlite是嵌入式关系数据库),

2>sqlite的需要加载的库文件已经加载

3>($options可以有3.2得出)$options['cache_db_complete_path']存在,则$backendType='sqlite'

总结:

是通过$type的值,库文件的存在性,$options['cache_db_complete_path']是否存在值,进而决定$backendType的值。

------------------>得出$backendTyoe的值

注:

$options['cache_db_complete_path'] = $cacheOptions['backend_options']['cache_db_complete_path']。

3.4

//4

case 'memcached':

if (extension_loaded('memcache')) {

if (isset($cacheOptions['memcached'])) {

$options = $cacheOptions['memcached'];

}

$enable2levels = true;

$backendType = 'Memcached';

}

break;

mencache:内存显示情况。

如果

存在memcached需要加载的库文件则$enable2levels = true;$backendType ='Memcached';

如果

1.存在memcached需要加载的库文件

2.isset($cacheOptions['memcached'])

则$options = $cacheOptions['memcached'].

如果条件成立->------------------>得出$enable2levels和$backendType的值,对$options重新赋值

3.5

case 'apc':

if (extension_loaded('apc') && ini_get('apc.enabled')) {

$enable2levels = true;

$backendType = 'Apc';

}

break;

如果apc的库文件加载,而且int_get('apc.enabled')

则$enable2levels =true, $backendType ='Apc'

3.6

case 'xcache':

if (extension_loaded('xcache')) {

$enable2levels = true;

$backendType = 'Xcache';

}

break;

如果加载了xcache的扩展库文件,则$enable2levels=true,$backendType='Xcache'.

3.7

case 'varien_cache_backend_eaccelerator':

if (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) {

$enable2levels = true;

$backendType = 'Varien_Cache_Backend_Eaccelerator';

}

break;

如果eaccelerator的扩展库文件加载,ini_get('eaccelerator.enable')

$enable2levels = true;

$backendType = 'Varien_Cache_Backend_Eaccelerator';

3.8

case 'database':

$backendType = 'Varien_Cache_Backend_Database';

$options = $this->getDbAdapterOptions();

break;

如果为database

$backendType = 'Varien_Cache_Backend_Database';

$options = $this->getDbAdapterOptions();

3.8.1

/**

* Get options for database backend type

*

* @return array

*/

protected function getDbAdapterOptions()

{

$options['adapter_callback'] = array($this, 'getDbAdapter');

$options['data_table'] = Mage::getSingleton('core/resource')->getTableName('core/cache');

$options['tags_table'] = Mage::getSingleton('core/resource')->getTableName('core/cache_tag');

return $options;

}

得到$options['adapter_callback'] ,$options['data_table'],$options['tags_table']的值。

3.9

default:

if ($type != $this->_defaultBackend) {

try {

if (class_exists($type, true)) {

$implements = class_implements($type, true);

if (in_array('Zend_Cache_Backend_Interface', $implements)) {

$backendType = $type;

}

}

} catch (Exception $e) {

}

}

}

如果type不等于$this->_defaultBackend(此值为'file'),而且存在type这个类,这个类实现了zend_cache_backend_INterface这个接口。

$backendType = $type;

3.10

if (!$backendType) {

$backendType = $this->_defaultBackend;

foreach ($this->_defaultBackendOptions as $option => $value) {

if (!array_key_exists($option, $options)) {

$options[$option] = $value;

}

}

}

3.10.1

/**

* Default iotions for default backend

*

* @var array

*/

protected $_defaultBackendOptions = array(

'hashed_directory_level' => 1,

'hashed_directory_umask' => 0777,

'file_name_prefix' => 'mage',

);

如果backendType没有值,也就是上面的这些情况下都没有给backendType赋值,则等于默认值file($this->_defaultBackend),如果$this->_defaultBackendOptions的key值不存在于$options中,则将该key-value加入到$options。

3.11

//11

$backendOptions = array('type' => $backendType, 'options' => $options);

if ($enable2levels) {

$backendOptions = $this->_getTwoLevelsBackendOptions($backendOptions, $cacheOptions);

}

return $backendOptions;

}

3.11.1

$backendOptions = array('type' => $backendType, 'options' => $options);

return $backendOptions

3.11.2

if ($enable2levels) {

$backendOptions = $this->_getTwoLevelsBackendOptions($backendOptions, $cacheOptions);

}

return $backendOptions;

3.11.2.1

/**

* Initialize two levels backend model options

*

* @param array $fastOptions fast level backend type and options

* @param array $cacheOptions all cache options

* @return array

*/

protected function _getTwoLevelsBackendOptions($fastOptions, $cacheOptions)

{

$options = array();

$options['fast_backend'] = $fastOptions['type'];

$options['fast_backend_options'] = $fastOptions['options'];

$options['fast_backend_custom_naming'] = true;

$options['fast_backend_autoload'] = true;

$options['slow_backend_custom_naming'] = true;

$options['slow_backend_autoload'] = true;

if (isset($cacheOptions['slow_backend'])) {

$options['slow_backend'] = $cacheOptions['slow_backend'];

} else {

$options['slow_backend'] = $this->_defaultBackend;

}

if (isset($cacheOptions['slow_backend_options'])) {

$options['slow_backend_options'] = $cacheOptions['slow_backend_options'];

} else {

$options['slow_backend_options'] = $this->_defaultBackendOptions;

}

if ($options['slow_backend'] == 'database') {

$options['slow_backend'] = 'Varien_Cache_Backend_Database';

$options['slow_backend_options'] = $this->getDbAdapterOptions();

}

$backend = array(

'type' => 'TwoLevels',

'options' => $options

);

return $backend;

}

//由于不是很懂cache,对于这些复杂的赋值,只知道赋值的结果,而不知道这些赋值有什么作用,现就分析到这里吧。总归

$backendOptions = array('type' => $backendType, 'options' => $options);

return $backendOptions

返回一个type和options的数组。

type指明类型: file,database,eaccelerator,xcache,apc,memcached,sqlite等

options指明: 这个type需要用到的一个数值,options是一个数组,包含需要用到的值对。

4

$frontend = $this->_getFrontendOptions($options);

/**

* Get options of cache frontend (options of Zend_Cache_Core)

*

* @param array $cacheOptions

* @return array

*/

protected function _getFrontendOptions(array $cacheOptions)

{

$options = isset($cacheOptions['frontend_options']) ? $cacheOptions['frontend_options'] : array();

if (!array_key_exists('caching', $options)) {

$options['caching'] = true;

}

if (!array_key_exists('lifetime', $options)) {

$options['lifetime'] = isset($cacheOptions['lifetime']) ? $cacheOptions['lifetime'] : self::DEFAULT_LIFETIME;

}

if (!array_key_exists('automatic_cleaning_factor', $options)) {

$options['automatic_cleaning_factor'] = 0;

}

$options['cache_id_prefix'] = $this->_idPrefix;

return $options;

}

5

$this->_frontend = Zend_Cache::factory('Varien_Cache_Core', $backend['type'], $frontend, $backend['options'],

true, true, true

);

Mage_Core_Model_Cache->_frontend的赋值:

5.1

/**

* Factory

*

* @param mixed $frontend frontend name (string) or Zend_Cache_Frontend_ object

* @param mixed $backend backend name (string) or Zend_Cache_Backend_ object

* @param array $frontendOptions associative array of options for the corresponding frontend constructor

* @param array $backendOptions associative array of options for the corresponding backend constructor

* @param boolean $customFrontendNaming if true, the frontend argument is used as a complete class name ; if false, the frontend argument is used as the end of "Zend_Cache_Frontend_[...]" class name

* @param boolean $customBackendNaming if true, the backend argument is used as a complete class name ; if false, the backend argument is used as the end of "Zend_Cache_Backend_[...]" class name

* @param boolean $autoload if true, there will no #require_once for backend and frontend (usefull only for custom backends/frontends)

* @throws Zend_Cache_Exception

* @return Zend_Cache_Core|Zend_Cache_Frontend

*/

public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array(), $customFrontendNaming = false, $customBackendNaming = false, $autoload = false)

{

if (is_string($backend)) {

//1

$backendObject = self::_makeBackend($backend, $backendOptions, $customBackendNaming, $autoload);

} else {

if ((is_object($backend)) && (in_array('Zend_Cache_Backend_Interface', class_implements($backend)))) {

$backendObject = $backend;

} else {

self::throwException('backend must be a backend name (string) or an object which implements Zend_Cache_Backend_Interface');

}

}

if (is_string($frontend)) {

$frontendObject = self::_makeFrontend($frontend, $frontendOptions, $customFrontendNaming, $autoload);

} else {

if (is_object($frontend)) {

$frontendObject = $frontend;

} else {

self::throwException('frontend must be a frontend name (string) or an object');

}

}

$frontendObject->setBackend($backendObject);

return $frontendObject;

}

5.1.1

/**

* Frontend Constructor

*

* @param string $backend

* @param array $backendOptions

* @param boolean $customBackendNaming

* @param boolean $autoload

* @return Zend_Cache_Backend

*/

public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false)

{

if (!$customBackendNaming) {

//1

$backend = self::_normalizeName($backend);

}

if (in_array($backend, Zend_Cache::$standardBackends)) {

// we use a standard backend

$backendClass = 'Zend_Cache_Backend_' . $backend;

// security controls are explicit

#require_once str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php';

} else {

// we use a custom backend

if (!preg_match('~^[/w]+$~D', $backend)) {

Zend_Cache::throwException("Invalid backend name [$backend]");

}

if (!$customBackendNaming) {

// we use this boolean to avoid an API break

$backendClass = 'Zend_Cache_Backend_' . $backend;

} else {

$backendClass = $backend;

}

if (!$autoload) {

$file = str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php';

if (!(self::_isReadable($file))) {

self::throwException("file $file not found in include_path");

}

#require_once $file;

}

}

return new $backendClass($backendOptions);

}

5.1.1

/**

* Normalize frontend and backend names to allow multiple words TitleCased

*

* @param string $name Name to normalize

* @return string

*/

protected static function _normalizeName($name)

{

$name = ucfirst(strtolower($name));

$name = str_replace(array('-', '_', '.'), ' ', $name);

$name = ucwords($name);

$name = str_replace(' ', '', $name);

return $name;

}

标准化这个名字,例如由mage_core_model_config-->mageCoreModelConfig.

总结:

$this->_frontend = Zend_Cache::factory('Varien_Cache_Core', $backend['type'], $frontend, $backend['options'],

true, true, true

);

返回值为

Zend_Cache_Core|Zend_Cache_Frontend,

6

if (isset($options['request_processors'])) {

$this->_requestProcessors = $options['request_processors'];

}

总结:

根据传入值$options,

得到

1

$this->_defaultBackendOptions['cache_dir'] = Mage::getBaseDir('cache');

2

$this->_idPrefix

3

//backend和$frontend类型为数组。返回一个包含type和options的数组。

$backend = $this->_getBackendOptions($options);

$frontend = $this->_getFrontendOptions($options);

进而得出

$this->_frontend = Zend_Cache::factory('Varien_Cache_Core', $backend['type'], $frontend, $backend['options'],

true, true, true

);

$this->_frontend 为Zend_Cache_Core|Zend_Cache_Frontend类型

4

$this->_requestProcessors = $options['request_processors'];

对cache的机制了解不是很多,还处于模糊阶段,所以对magento的核心cache不能有很好的理解,就先这样吧,知道个大体结构。到此为止。。

magento 的cache机制是zendframework框架的,所以,研究这个框架再回来看magento的核心内存机制cache。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics