Magento工厂名及函数

Magento Alan 10年前 (2014-07-03) 4012次浏览 0个评论 扫描二维码

Magento通过工厂方法(factory method)来实例化Model, Helper和Block类。一个工厂方法就是一种设计模式,用于通过一个类的别名来实例化一个对象,而无需使用具体的类别。
Magento采用了如下几个工厂方法:

  • Mage::getModel()
  • Mage::getResourceModel()
  • Mage::helper()
  • Mage::getSingleton()
  • Mage::getResourceSingleton()
  • Mage::getResourceHelper()

每个方法能通过类的别名来决定我们所要实例化的对象的真实类名,比如我们想要实例化product对象,可以通过调用getModel()方法来实现:

$product = Mage::getModel('catalog/product');

注意我们所传入的工厂名由group_classname/model_
name所组成,Magento会将其解析为一个真实的类名Mage_Catalog_Model_
Product。下面让我们来分析一下getModel()方法的内部机制:

public static function getModel($modelClass = '', $arguments =

array())

	{

	return self::getConfig()->getModelInstance

	($modelClass, $arguments);

	}

getModel调用了Mage_Core_Model_Config类中的getModelInstance方法:

public function getModelInstance($modelClass='',

$constructArguments=array())

{

	$className = $this->getModelClassName($modelClass);

	if (class_exists($className)) {

		Varien_Profiler::start('CORE::create_object_of::'.$className);

		$obj = new $className($constructArguments);

		Varien_Profiler::stop('CORE::create_object_of::'.$className);

		return $obj;

	} else {

		return false;

	}

}

getModelInstance()又调用getModelClassName()方法,该方法将我们类的别名作一个参数,然后尝试验证所返回类是否存在,如果该类存在,则为该类创建一个实例并将其返回到getModel()方法中:


public function getModelClassName($modelClass)

{

	$modelClass = trim($modelClass);

	if (strpos($modelClass, '/')===false) {

		return $modelClass;

	}

	return $this->getGroupedClassName('model', $modelClass);

}

getModelClassName()调用getGroupedClassName()方法(/app/code/core/Mage/Core/Model/Config.php),该方法用于返回模型中真实的类别。getGroupedClassName()中有$groupType和$classId两个参数,$groupType代表我们所要实例化的对象类型(当前仅支持model, block和helper),$classId就是我们所要实例化的类。

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;

        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  is left

             * to keep name of previously used nodes, that still may be used by non-updated extensions.

             */

            if (isset($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;

    }

可以看出,主要工作在getGroupedClassName()中进行,该方法获取类别名catalog/product并通过explode方法去除中间的斜线并创建一个数组。然后该方法加载VarienSimplexml_Element的实例并将数组中的第一个值(group_classname)传入,同时它还是检查此类是否被重写,如果被重写,将会采用相对应的组名。
Magento还使用自定义的uc_words()方法来将首字母大写并还可以转化类别名的分隔符。最终,函数会将真实类名返回给getModelInstance()方法,在这个例子中,返回值为Mage_Catalog_Model_Product。
Magento工厂名及函数

喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址