magento中,是没法通过Mage::getModel("xx/xx")配合xml中的<rewrite>实现abstruct class的rewrite。 为什么?这需要详细了解一下magento中model的rewrite原理。
假设xml中我们定义了如下的rewrite:
<customer>
<rewrite>
<customer>Newjueqi_Customer_Model_Customer</customer>
</rewrite>
</customer>
根据配置,我们是把 Mage_Customer_Model_Customer rewrite为 Newjueqi_Customer_Model_Customer。
那么,在执行 Mage::getModel('customer/customer') 时,magento到底做了什么?我们分析一下源码:
1. 首先来到getmodel方法
public static function getModel($modelClass = '', $arguments = array())
{
//获取class实例
return self::getConfig()->getModelInstance($modelClass, $arguments);
}
2. 看一下magento是怎么生成实例的
public function getModelInstance($modelClass='', $constructArguments=array())
{
//获取类的名称,rewrite的关键就在与怎么把原来要生成的类名Mage_Customer_Model_Customer 换成 Newjueqi_Customer_Model_Customer。
$className = $this->getModelClassName($modelClass);
if (class_exists($className)) {
Varien_Profiler::start('CORE::create_object_of::'.$className);
//通过new的方法来产生一个类的实例
$obj = new $className($constructArguments);
Varien_Profiler::stop('CORE::create_object_of::'.$className);
return $obj;
} else {
/* throw Mage::exception(
'Mage_Core',
Mage::helper('core')->__('Model class does not exist: %s.', $modelClass)
); */
return false;
}
}
3. 好,最后看一下magento是怎么把生成的类名Mage_Customer_Model_Customer 换成 Newjueqi_Customer_Model_Customer。
//对类名检验
public function getModelClassName($modelClass)
{
$modelClass = trim($modelClass);
if (strpos($modelClass, '/')===false) {
return $modelClass;
}
return $this->getGroupedClassName('model', $modelClass);
}
//获取所生成class的实际类名
public function getGroupedClassName($groupType, $classId, $groupRootNode=null)
{
if (empty($groupRootNode)) {
$groupRootNode = 'global/'.$groupType.'s';
}
$classArr = explode('/', trim($classId));
$group = $classArr[0];
$class = !empty($classArr[1]) ? $classArr[1] : null;
if (isset($this->_classNameCache[$groupRootNode][$group][$class])) {
return $this->_classNameCache[$groupRootNode][$group][$class];
}
$config = $this->_xml->global->{$groupType.'s'}->{$group};
// First - check maybe the entity class was rewritten
$className = null;
/*
$className = (string)$config->rewrite->$class;
这里就是rewrite最关键的地方,magento已经在xml中找到“customer/customer”,
接着magento会找一下<customer>标签下是否有<rewrite>标签,如果找到的话,就会把rewrite标签中的类名替换实际类名
<customer>
<rewrite>
<customer>Newjueqi_Customer_Model_Customer</customer>
</rewrite>
</customer>
从上面的xml配置可知,是把“customer/customer”确定为Newjueqi_Customer_Model_Customer
*/
if (isset($config->rewrite->$class)) {
$className = (string)$config->rewrite->$class;
} else {
/**
* Backwards compatibility for pre-MMDB extensions.
* In MMDB release resource nodes <..._mysql4> were renamed to <..._resource>. So <deprecatedNode> is left
* to keep name of previously used nodes, that still may be used by non-updated extensions.
*/
if ($config->deprecatedNode) {
$deprecatedNode = $config->deprecatedNode;
$configOld = $this->_xml->global->{$groupType.'s'}->$deprecatedNode;
if (isset($configOld->rewrite->$class)) {
$className = (string) $configOld->rewrite->$class;
}
}
}
// Second - if entity is not rewritten then use class prefix to form class name
if (empty($className)) {
if (!empty($config)) {
$className = $config->getClassName();
}
if (empty($className)) {
$className = 'mage_'.$group.'_'.$groupType;
}
if (!empty($class)) {
$className .= '_'.$class;
}
$className = uc_words($className);
}
$this->_classNameCache[$groupRootNode][$group][$class] = $className;
return $className;
}
看了上面的源码分析,我们可总结一下magento的rewrite机制:
1. 在xml文件中构造Mage::getModel('xxx/xxx')中所对应'xxx/xxx'所对应的实际类名,如果<rewrite>标签存在就使用<rewrite>标签中的类名,否则就用实际类名。
2. 使用$obj = new $className($constructArguments) 生成类的实例。
由以上的分析可知,magento的rewrite最后是调用 new 来生成一个类的实例,但在php中,abstruct class是没法生成类的实例的,所以abstruct class是没法rewrite。
【文章作者】曾健生
【作者邮箱】zengjiansheng1@126.com
【作者QQ】190678908
【作者博客】blog.csdn.net/newjueqi
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)