2011-1-3----mage_core_model_config---------init()方法加载过程---个人分析

****************************************************************************

Mage_core_mode_config

的init过程。

/**

* Initialization of core configuration

*

* @return Mage_Core_Model_Config

*/

public function init($options=array())

{

$this->setCacheChecksum(null);

$this->_cacheLoadedSections = array();

$this->setOptions($options);

$this->loadBase();

$cacheLoad = $this->loadModulesCache();

if ($cacheLoad) {

return $this;

}

$this->loadModules();

$this->loadDb();

$this->saveCache();

return $this;

}

1.

$this->setCacheChecksum(null);

/**

* Enter description here...

*

* @param string $data

* @return Varien_Simplexml_Config

*/

public function setCacheChecksum($data)

{

if (is_null($data)) {

$this->_cacheChecksum = null;

} elseif (false===$data || 0===$data) {

$this->_cacheChecksum = false;

} else {

$this->_cacheChecksum = md5($data);

}

return $this;

}

//总结:

对$data用md5加密。然后赋值给$this->_cacheChecksum.

2

$this->_cacheLoadedSections = array();

/**

* Loaded Configuration by cached sections

*

* @var array

*/

protected $_cacheLoadedSections = array();

3

$this->setOptions($options);

如果传入的数据中有$options,则赋值

$this->getOptions()->addData($options);

4

$this->loadBase();

/**

* Load base system configuration (config.xml and local.xml files)

*

* @return Mage_Core_Model_Config

*/

public function loadBase()

{

$etcDir = $this->getOptions()->getEtcDir();

$files = glob($etcDir.DS.'*.xml');

$this->loadFile(current($files));

while ($file = next($files)) {

$merge = clone $this->_prototype;

$merge->loadFile($file);

$this->extend($merge);

}

if (in_array($etcDir.DS.'local.xml', $files)) {

$this->_isLocalConfigLoaded = true;

}

return $this;

}

4.1

$etcDir = $this->getOptions()->getEtcDir();

4.1.1

//MAGE_CORE_MODEL_CONFIG_OPTIONS

public function getEtcDir()

{

//return $this->getDataSetDefault('etc_dir', $this->getAppDir().DS.'etc');

return $this->_data['etc_dir'];

}

在 MAGE_CORE_MODEL_CONFIG_OPTIONS 初始化函数里面:

$this->_data['etc_dir'] = $appRoot.DS.'etc';

//总结

得到的是app/ect

4.2

//glob()函数的作用是:以数组的形式返回与指定模式相匹配的文件名或目录

$files = glob($etcDir.DS.'*.xml');

//app/etc下面的所有配置文件。

4.3

$this->loadFile(current($files));

4.3.1

current (array &$array)

//return mixed The current function simply returns the

* value of the array element that's currently being pointed to by the

* internal pointer. It does not move the pointer in any way. If the

* internal pointer points beyond the end of the elements list or the array is

* empty, current returns false.

4.3.2

/**

* Imports XML file

*

* @param string $filePath

* @return boolean

*/

public function loadFile($filePath)

{

if (!is_readable($filePath)) {

//throw new Exception('Can not read xml file '.$filePath);

return false;

}

$fileData = file_get_contents($filePath);

$fileData = $this->processFileData($fileData);

return $this->loadString($fileData, $this->_elementClass);

}

4.3.2.1

// Reads entire file into a string

$fileData = file_get_contents($filePath);

4.3.2.2

// processFileData

/**

* Stub method for processing file data right after loading the file text

*

* @param string $text

* @return string

*/

public function processFileData($text)

{

return $text;

}

4.3.2.3

//$this->loadString($fileData, $this->_elementClass);

/**

* Imports XML string

*

* @param string $string

* @return boolean

*/

public function loadString($string)

{

if (is_string($string)) {

$xml = simplexml_load_string($string, $this->_elementClass);

if ($xml instanceof Varien_Simplexml_Element) {

$this->_xml = $xml;

return true;

}

} else {

Mage::logException(new Exception('"$string" parameter for simplexml_load_string is not a string'));

}

return false;

}

4.3.2.3.1

$fileData = file_get_contents($filePath);

$this->_elementClass就是在mode/config/base.php初始化的时候,赋值的

$this->_elementClass = 'Mage_Core_Model_Config_Element';

4.3.2.3.2

//Interprets a string of XML into an object

//return SimpleXMLElement an object of class SimpleXMLElement with

* properties containing the data held within the XML document

simplexml_load_string()

通过一个xml文件,返回一个SimpleXMLElement类型的对象。

//

$xml = simplexml_load_string($string, $this->_elementClass);

从这里看。貌似mage_core_model_config_element是从把string变成xml对象(Varien_Simplexml_Element类型的对象)服务的。

4.3.2.3.3

$xml instanceof Varien_Simplexml_Element

判断$xml是否为Varien_Simplexml_Element()类型的对象。

小结:首先找到配置文件目录,然后通过file_get_contents($filePath),把文件读取到string中,通过$xml = simplexml_load_string($string, $this->_elementClass),

生成Varien_Simplexml_Element()类型的对象。

$this->loadFile(current($files));的作用就是读取xml文件,生成Varien_Simplexml_Element,赋值于$this->_xml.

故mage_core_model_config_element为读取xml生成varien_simplexml_element对象。

4.4

$merge = clone $this->_prototype;

$merge->loadFile($file);

$this->extend($merge);

4.4.1

$merge->loadFile($file);

和4.3---$this->loadFile(),是一样的效果,不过他写入的类是:mage_core_model_config_base 生成的对象$merge的属性--->_xml(varien_simplexml_Element),

4.4.2

$this->extend($merge);

/**

* Enter description here...

*

* @param Varien_Simplexml_Config $config

* @param boolean $overwrite

* @return Varien_Simplexml_Config

*/

public function extend(Varien_Simplexml_Config $config, $overwrite=true)

{

$this->getNode()->extend($config->getNode(), $overwrite);

return $this;

}

4.4.2.1

$this->getNode();

/**

* Returns node found by the $path

*

* @see Varien_Simplexml_Element::descend

* @param string $path

* @return Varien_Simplexml_Element

*/

public function getNode($path=null)

{

if (!$this->_xml instanceof Varien_Simplexml_Element) {

return false;

} elseif ($path === null) {

return $this->_xml;

} else {

return $this->_xml->descend($path);

}

}

//

如果$path不是Varien_simplexml_element,则return flase

//

如果$path是null,返回xml,

//

如果不为空,则返回$this->_xml->descend($path);

4.4.2.2

$this->getNode()->extend($config->getNode(), $overwrite);

//$this->getNode()返回的是一个varien_simplexml_element()对象类型。

/**

* Extends current node with xml from $source

*

* If $overwrite is false will merge only missing nodes

* Otherwise will overwrite existing nodes

*

* @param Varien_Simplexml_Element $source

* @param boolean $overwrite

* @return Varien_Simplexml_Element

*/

public function extend($source, $overwrite=false)

{

if (!$source instanceof Varien_Simplexml_Element) {

return $this;

}

foreach ($source->children() as $child) {

$this->extendChild($child, $overwrite);

}

return $this;

}

4.4.2.2.1

$source->children()

//PHP库函数,Finds children of given node

public function children ($ns = null, $is_prefix = null) {}

4.4.2.2.2

//扩展一个子节点

$this->extendChild($child, $overwrite);

/**

* Extends one node

*

* @param Varien_Simplexml_Element $source

* @param boolean $overwrite

* @return Varien_Simplexml_Element

*/

public function extendChild($source, $overwrite=false)

{

// this will be our new target node

$targetChild = null;

// name of the source node

$sourceName = $source->getName();

// here we have children of our source node

$sourceChildren = $source->children();

if (!$source->hasChildren()) {

// handle string node

if (isset($this->$sourceName)) {

// if target already has children return without regard

if ($this->$sourceName->children()) {

return $this;

}

if ($overwrite) {

unset($this->$sourceName);

} else {

return $this;

}

}

$targetChild = $this->addChild($sourceName, $source->xmlentities());

$targetChild->setParent($this);

foreach ($source->attributes() as $key=>$value) {

$targetChild->addAttribute($key, $this->xmlentities($value));

}

return $this;

}

if (isset($this->$sourceName)) {

$targetChild = $this->$sourceName;

}

if (is_null($targetChild)) {

// if child target is not found create new and descend

$targetChild = $this->addChild($sourceName);

$targetChild->setParent($this);

foreach ($source->attributes() as $key=>$value) {

$targetChild->addAttribute($key, $this->xmlentities($value));

}

}

// finally add our source node children to resulting new target node

foreach ($sourceChildren as $childKey=>$childNode) {

$targetChild->extendChild($childNode, $overwrite);

}

return $this;

}

//小结:

将每个xml文件生成的varien_simplexml_element(加载xml),然后通过$this->extend()方法加载原理是:

while ($file = next($files)) {

$merge = clone $this->_prototype;

$merge->loadFile($file);

$this->extend($merge);

}

//return Varien_Simplexml_Config

$this->extend($merge);

//总结:

loadBase函数,读取app/etc/ 下面的所有xml文件,生成varien_simplexml_element对象,赋值于mage_core_model_config 的属性 _xml ,然后mage_core_model_config->loadFole(current($files)),也就是mage_core_model_config读取files数组里面的第一个file,加载,然后通过,This->_prototype(mage_core_model_base),读取next(files),$this->extend((clone $this->_prototype)->loadFile($file));

extend()函数加载子节点

$this为mage_core_model_config;

(clone $this->_prototype)->loadFile($file)为加载xml文件生成varien_simplexml_element对象。

while ($file = next($files)) {

$merge = clone $this->_prototype;

$merge->loadFile($file);

$this->extend($merge);

}

总结:

1.首先mage_core_model_config->loadFile()加载第一个file生成varien_simplexml_element,

2剩下的file,通过mage_core_model_config_base->loadFile($file)加载,

3将mage_core_model_config和mage_core_model_config_base合并

mage_core_model_config->extend(mage_core_model_config_base).

//@return Mage_Core_Model_Config

$this->loadBase();

加载app/etc/下面的所有的xml文件,然后赋值于Mage_Core_Model_Config->_xml.

完成对所有xml文件的加载。

4.5

if (in_array($etcDir.DS.'local.xml', $files)) {

$this->_isLocalConfigLoaded = true;

}

//Checks if a value exists in an array

in_array

/**

* Flag which identify what local configuration is loaded

*

* @var bool

*/

protected $_isLocalConfigLoaded = false;

5

$cacheLoad = $this->loadModulesCache();

if ($cacheLoad) {

return $this;

}

5.1

//$this->loadModulesCache();

/**

* Load cached modules configuration

*

* @return bool

*/

public function loadModulesCache()

{

if (Mage::isInstalled()) {

if ($this->_canUseCacheForInit()) {

Varien_Profiler::start('mage::app::init::config::load_cache');

$loaded = $this->loadCache();

Varien_Profiler::stop('mage::app::init::config::load_cache');

if ($loaded) {

$this->_useCache = true;

return true;

}

}

}

return false;

}

5.1.1

Mage::isInstalled()

/**

* Retrieve application installation flag

*

* @param string|array $options

* @return bool

*/

public static function isInstalled($options = array())

{

if (self::$_isInstalled === null) {

self::setRoot();

if (is_string($options)) {

$options = array('etc_dir' => $options);

}

$etcDir = 'etc';

if (!empty($options['etc_dir'])) {

$etcDir = $options['etc_dir'];

}

$localConfigFile = self::getRoot() . DS . $etcDir . DS . 'local.xml';

self::$_isInstalled = false;

if (is_readable($localConfigFile)) {

$localConfig = simplexml_load_file($localConfigFile);

date_default_timezone_set('UTC');

if (($date = $localConfig->global->install->date) && strtotime($date)) {

self::$_isInstalled = true;

}

}

}

return self::$_isInstalled;

}

5.1.1.1

// self::setRoot();

/**

* Set application root absolute path

*

* @param string $appRoot

* @throws Mage_Core_Exception

*/

public static function setRoot($appRoot = '')

{

if (self::$_appRoot) {

return ;

}

if ('' === $appRoot) {

// automagically find application root by dirname of Mage.php

$appRoot = dirname(__FILE__);

}

$appRoot = realpath($appRoot);

if (is_dir($appRoot) and is_readable($appRoot)) {

self::$_appRoot = $appRoot;

} else {

self::throwException($appRoot . ' is not a directory or not readable by this user');

}

}

5.1.2

$this->_canUseCacheForInit()

/**

* Check if cache can be used for config initialization

*

* @return bool

*/

protected function _canUseCacheForInit()

{

return Mage::app()->useCache('config') && $this->_allowCacheForInit

&& !$this->_loadCache($this->_getCacheLockId());

}

5.1.2.1

Mage::app()->useCache('config')

/**

* Check whether to use cache for specific component

*

* @return boolean

*/

public function useCache($type=null)

{

return $this->_cache->canUse($type);

}

5.1.2.1.1

/**

* Cache object

*

* @var Zend_Cache_Core

*/

protected $_cache;

5.1.2.2

$this->_allowCacheForInit

/**

* Flach which allow using cache for config initialization

*

* @var bool

*/

protected $_allowCacheForInit = true;

5.1.2.3

$this->_loadCache($this->_getCacheLockId());

5.1.2.3.1

/**

* Get lock flag cache identifier

*

* @return string

*/

protected function _getCacheLockId()

{

return $this->getCacheId().'.lock';

}

5.1.2.3.1.1

/**

* Enter description here...

*

* @return string

*/

public function getCacheId()

{

return $this->_cacheId;

}

5.1.2.3.2

$this->_loadCache()

/**

* Load cached data by identifier

*

* @param string $id

* @return string

*/

protected function _loadCache($id)

{

return Mage::app()->loadCache($id);

}

5.1.2.3.2.1

/**

* Loading cache data

*

* @param string $id

* @return mixed

*/

public function loadCache($id)

{

return $this->_cache->load($id);

}

5.1.3

$loaded = $this->loadCache();

/**

* Enter description here...

*

* @return boolean

*/

public function loadCache()

{

if (!$this->validateCacheChecksum()) {

return false;

}

$xmlString = $this->_loadCache($this->getCacheId());

$xml = simplexml_load_string($xmlString, $this->_elementClass);

if ($xml) {

$this->_xml = $xml;

$this->setCacheSaved(true);

return true;

}

return false;

}

6

$this->loadModules();

6.1

/**

* Load modules configuration

*

* @return Mage_Core_Model_Config

*/

public function loadModules()

{

Varien_Profiler::start('config/load-modules');

$this->_loadDeclaredModules();

$this->loadModulesConfiguration('config.xml', $this);

/**

* Prevent local.xml directives overwriting

*/

$mergeConfig = clone $this->_prototype;

$this->_isLocalConfigLoaded = $mergeConfig->loadFile($this->getOptions()->getEtcDir().DS.'local.xml');

if ($this->_isLocalConfigLoaded) {

$this->extend($mergeConfig);

}

$this->applyExtends();

Varien_Profiler::stop('config/load-modules');

return $this;

}

6.1.1

$this->_loadDeclaredModules();

/**

* Load declared modules configuration

*

* @param null $mergeConfig depricated

* @return Mage_Core_Model_Config

*/

protected function _loadDeclaredModules($mergeConfig = null)

{

$moduleFiles = $this->_getDeclaredModuleFiles();

if (!$moduleFiles) {

return ;

}

Varien_Profiler::start('config/load-modules-declaration');

$unsortedConfig = new Mage_Core_Model_Config_Base();

$unsortedConfig->loadString('<config/>');

$fileConfig = new Mage_Core_Model_Config_Base();

// load modules declarations

foreach ($moduleFiles as $file) {

$fileConfig->loadFile($file);

$unsortedConfig->extend($fileConfig);

}

$moduleDepends = array();

foreach ($unsortedConfig->getNode('modules')->children() as $moduleName => $moduleNode) {

$depends = array();

if ($moduleNode->depends) {

foreach ($moduleNode->depends->children() as $depend) {

$depends[$depend->getName()] = true;

}

}

$moduleDepends[$moduleName] = array(

'module' => $moduleName,

'depends' => $depends,

'active' => ('true' === (string)$moduleNode->active ? true : false),

);

}

// check and sort module dependens

$moduleDepends = $this->_sortModuleDepends($moduleDepends);

// create sorted config

$sortedConfig = new Mage_Core_Model_Config_Base();

$sortedConfig->loadString('<config><modules/></config>');

foreach ($unsortedConfig->getNode()->children() as $nodeName => $node) {

if ($nodeName != 'modules') {

$sortedConfig->getNode()->appendChild($node);

}

}

foreach ($moduleDepends as $moduleProp) {

$node = $unsortedConfig->getNode('modules/'.$moduleProp['module']);

$sortedConfig->getNode('modules')->appendChild($node);

}

$this->extend($sortedConfig);

Varien_Profiler::stop('config/load-modules-declaration');

return $this;

}

6.1.1.1

//还不是很明白,应该是得到$string="<config.>"节点下所有数据的配置吧。类型为element。

/**

* Imports XML string

*

* @param string $string

* @return boolean

*/

public function loadString($string)

{

if (is_string($string)) {

$xml = simplexml_load_string($string, $this->_elementClass);

if ($xml instanceof Varien_Simplexml_Element) {

$this->_xml = $xml;

return true;

}

} else {

Mage::logException(new Exception('"$string" parameter for simplexml_load_string is not a string'));

}

return false;

}

//Interprets a string of XML into an object

//返回类 SimpleXMLElement 的一个对象,该对象的属性包含 XML 文档中的数据

$xml = simplexml_load_string($string, $this->_elementClass);

6.1.2

$this->loadModulesConfiguration('config.xml', $this);

//整合所有active的modules,然后把etc里面的内容整合。

//config-》loadString('<config/>');得到只有<config>子节点所在的xml的mage_core_model_config_element类型

/**

* Iterate all active modules "etc" folders and combine data from

* specidied xml file name to one object

*

* @param string $fileName

* @param null|Mage_Core_Model_Config_Base $mergeToObject

* @return Mage_Core_Model_Config_Base

*/

public function loadModulesConfiguration($fileName, $mergeToObject = null, $mergeModel=null)

{

$disableLocalModules = !$this->_canUseLocalModules();

if ($mergeToObject === null) {

$mergeToObject = clone $this->_prototype;

$mergeToObject->loadString('<config/>');

}

if ($mergeModel === null) {

$mergeModel = clone $this->_prototype;

}

$modules = $this->getNode('modules')->children();

foreach ($modules as $modName=>$module) {

if ($module->is('active')) {

if ($disableLocalModules && ('local' === (string)$module->codePool)) {

continue;

}

$configFile = $this->getModuleDir('etc', $modName).DS.$fileName;

if ($mergeModel->loadFile($configFile)) {

$mergeToObject->extend($mergeModel, true);

}

}

}

return $mergeToObject;

}

6.1.3

$mergeConfig = clone $this->_prototype;

$this->_isLocalConfigLoaded = $mergeConfig->loadFile($this->getOptions()->getEtcDir().DS.'local.xml');

6.1.4

$this->extend($mergeConfig);

6.1.5

$this->applyExtends();

7

$this->loadDb();

/**

* Load config data from DB

*

* @return Mage_Core_Model_Config

*/

public function loadDb()

{

if ($this->_isLocalConfigLoaded && Mage::isInstalled()) {

Varien_Profiler::start('config/load-db');

$dbConf = $this->getResourceModel();

$dbConf->loadToXml($this);

Varien_Profiler::stop('config/load-db');

}

return $this;

}

7.1

$dbConf = $this->getResourceModel();

/**

* Get config resource model

*

* @return Mage_Core_Store_Mysql4_Config

*/

public function getResourceModel()

{

if (is_null($this->_resourceModel)) {

$this->_resourceModel = Mage::getResourceModel('core/config');

}

return $this->_resourceModel;

}

7.2

$dbConf->loadToXml($this);

/**

* Load configuration values into xml config object

*

* @param Mage_Core_Model_Config $xmlConfig

* @param string $cond

* @return Mage_Core_Model_Mysql4_Config_Collection

*/

public function loadToXml(Mage_Core_Model_Config $xmlConfig, $cond=null)

8

$this->saveCache();

/**

* Save configuration cache

*

* @param array $tags cache tags

* @return Mage_Core_Model_Config

*/

public function saveCache($tags=array())

{

if (!Mage::app()->useCache('config')) {

return $this;

}

if (!in_array(self::CACHE_TAG, $tags)) {

$tags[] = self::CACHE_TAG;

}

$cacheLockId = $this->_getCacheLockId();

if ($this->_loadCache($cacheLockId)) {

return $this;

}

if (!empty($this->_cacheSections)) {

$xml = clone $this->_xml;

foreach ($this->_cacheSections as $sectionName => $level) {

$this->_saveSectionCache($this->getCacheId(), $sectionName, $xml, $level, $tags);

unset($xml->$sectionName);

}

$this->_cachePartsForSave[$this->getCacheId()] = $xml->asNiceXml('', false);

} else {

return parent::saveCache($tags);

}

$this->_saveCache(time(), $cacheLockId, array(), 60);

$this->removeCache();

foreach ($this->_cachePartsForSave as $cacheId => $cacheData) {

$this->_saveCache($cacheData, $cacheId, $tags, $this->getCacheLifetime());

}

unset($this->_cachePartsForSave);

$this->_removeCache($cacheLockId);

return $this;

}

8

$this->saveCache();

7.2

$dbConf->loadToXml($this);

5.1.3

$loaded = $this->loadCache();

6$this->loadModules();

需要在细致搞搞!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值