magento -- magento开发第一步-修改magento的代码实现特定的功能

magento开发第一步-修改magento的代码实现特定的功能

magento 的功能已经很强大,但是不同的客户还是有不同的需要,magento 不可能都能满足,要改变magento 的某些功能行为方式,就不可避免的要修改magento 的一些代码,如果只是直接在magento 的代码上修改也就没有什么可以说的,但是这样做不好的理由在于,这样会造成下次版本更新时的不便,而且有可能你一不小心更新了magento 版本而直接造成了你的修改的全部丢失。

 

那么有没有一种更好的方式来处理呢?一方面我们即可以实现修改了magento 的代码,一方面又不是直接在它的代码上修改而却又让magento 能够使用我们的代码。当然是可以的。magento 是在zend php framework上开发的,它承袭了zend的许多特性,采用了MVC的架构,也沿袭了zend的类名和目录嵌套相对应的特点。如:

 

class Mage_Catalog_Model_Category extends Mage_Catalog_Model_Abstract { /** * Category display modes */ const DM_PRODUCT = 'PRODUCTS'; const DM_PAGE = 'PAGE'; const DM_MIXED = 'PRODUCTS_AND_PAGE'; const TREE_ROOT_ID = 1;

 

这个类是保存在app/code/core/Mage/Catalog/Model/Category.php文件中,其中,core是代码池名,magento 默认自带了community,core,local三个代码池,其中core中保存了magento 自身的几乎所有的核心模块代码,Mage则是名字空间名。

 

我们将要说明的第一种最简单的改写magento 代码的方式便是利用了这种类名和目录相对应的特点,先分析一段magento 代码:

 

define('DS', DIRECTORY_SEPARATOR); define('PS', PATH_SEPARATOR); define('BP', dirname(dirname(__FILE__))); Mage::register('original_include_path', get_include_path()); if (defined('COMPILER_INCLUDE_PATH')) { $app_path = COMPILER_INCLUDE_PATH; set_include_path($app_path . PS . Mage::registry('original_include_path')); include_once "Mage_Core_functions.php"; include_once "Varien_Autoload.php"; } else { /** * Set include path */ $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local'; $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community'; $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core'; $paths[] = BP . DS . 'lib'; $app_path = implode(PS, $paths); set_include_path($app_path . PS . Mage::registry('original_include_path'));

 

其中,magento 在原有的包含路径上重新添加了它自己的几个包含路径(include path),分别是local,community,core代码池目录,然后是varien库目录,这样的顺序确定了PHP查询PHP类的顺序,分别是local,community,core,因为magento 并没有显式加载任何的库,而是利用了php的__autoload特性,分析一下下列的代码:

 

Varien_Autoload::register(); ... ... ... /** * Register SPL autoload function */ static public function register() { spl_autoload_register(array(self::instance(), 'autoload')); } ... ... ... /** * Load class source code * * @param string $class */ public function autoload($class) { if ($this->_collectClasses) { $this->_arrLoadedClasses[self::$_scope][] = $class; } if ($this->_isIncludePathDefined) { $classFile = $class; } else { $classFile = str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $class))); } $classFile.= '.php'; //echo $classFile;die(); return include $classFile; }

其中,下面的这行代码的作用是将当前所需要的类名转换成对应的文件:

第一个str_replace('_', ' ', $class);是将类名中的各个下划线替换成空格,并将每个单词第一个字母大写。

第二个str_replace则是将上一次调用返回的字符串中的空格替换成路径分隔符,也就是/,这样就确定了类所对应的文件位置。

$classFile = str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $class)));

 

我们前面知道了,magento 中的所有代码的类名都是以名字空间(namespace)为前缀,沿袭目录结构的嵌套层次。而各个代码池即可以有不一样的名字空间,也可以有不一样的名字空间。那么如果你在local代码池(目录)下面创建一个Mage名字空间(目录),那么你几乎可以重写 magento的任意一个类了。比如,我们要重写Mage_Catalog_Model_Category这个类,那么你可以创建下列的文件目录结构:

[BP]app/code/local/Mage/Catalog/Model/Category.php

 

这样你可以直接将原来的文件复制过来,然后你可以做任意修改了,而不用担心版本更新的问题。

 

上面的这种方法我已经测对model的重写了。block和controller还末测试,不过controller的加载方式似乎有所不同,有待测试。

 

这只是偷懒的一种方法,事实上magento推荐的方法是通过新建模块,然后在xml中配置重写相应的model,block,controller来实现的。这个过程要稍微复杂一点,我下次再写。

 

欢迎转载,请注明文章来源 magento博客,magento学习,magento模板设计

你可能感兴趣的:(Class,Path,include,Zend,autoload,Magento)