• CMS
    内容发布型网站
  • 结构清晰 易于发布
    功能强大 容易扩展
  • B2C
    购物型网站
  • 安全,优化,功能齐全
    及完善的后台管理
  • 客户定制
    系统开发
  • 用我们精湛的技术
    打造属于你的系统
  • 完善的
    解决方案
  • 业务背后是强大的
    开源社区, 你事业无忧
  • 后续
    技术支持
  • 稳定的后续技术支持
    为你的业务保驾护航

magento 程序开发1 - 简单介绍

浏览位置

在原创文章,引用请注明出处。http://cancms.com/content/blog/view/tag/magento/iid/50

作者: cancms.com 

文章提纲 :

  • Magetno 代码集中写在一个模块中
  • Magetno 是一个以配置为基础的MVC框架系统
  • 控制器
  • 以URI形式定义的类加载方式
  • 模型
  • 助手(Helper)
  • 内容布局(Layout)
  • 观察者(Observers)
  • 覆盖原始的模型

PHP代码集中写在一个模块中

magento系统由一个个的模块组成,每一个模块是一个小型的MVC系统。实现系统功能的代码就有组织地放在一个个的模块里面。

一个模块通常对应着一定的功能作用。如CUSTOMER模块就专门用来管理用户相关的信息;CHECKOUT模块就用来管理订单生成的处理过程;

CATALOG模块用来处理和产品,分类相关的信息。。。


Magento的代码:

如:在checkout模块里面,你可以看到模型,控制器,助手,内容块等相关的代码

app/code/core/Mage/Checkout

app/code/core/Mage/Checkout, 在这个目录路径中,Mage是一个公司的名字,以它自己的名字作为一个命名空间,Checkout是在这个空间下面的一个模块,通常意味着它是这个公司开发的一个模块。

你自己的代码:

当你要开发定制的功能,写自己的代码时,不必直接修改Magento原有代码,或者做在Mage里面新增加文件夹之类的事情,你可以增加属于你自己的模块,用来放置你的代码。


app/code/core/Package/Modulename


这里的Package可以以你公司/组织的名字来命名。这个方式可以使世界上每个组织都有一个相对独立的名字来存放他们自己的模块,也就可以避免命名冲突这个问题。

当你新建了一个属于你自己的模块时,你需要把这个模块的相关信息告诉Magento,这样它才会对你模块进行有效加载。声明模块可以在这个文件夹里面添加xml文件:


app/etc/modules


在这个文件夹里面有两种类型的文件,第一种xml文件的方式用来声明一个独立的模块,它的命名方式是:

Packagename_Modulename.xml

第二种xml文件,用一个xml文件来声明一个pacakage下面的多个模块,它的命名方式为:Packagename_All.xml。 这个方式是magento核心开发团队的命名方式,Mage_All.xml声明了

该团队的多个模块。并不建议其它开发者也以这个方式来命名他们的模块,因为这个方式要把多个模块的声明放在同一个文件,破坏了模块的独立性。


以配置为基础的MVC框架系统

Magento 的MVC框架与传统的MVC框架系统有一点不同。传统的MVC系统在通常的情况,如果你要增加一个控制器或者模型,直接在指定的地方增加一个文件或者类,然后系统会自动的


获取你新增加的类。

Magento的MVC以配置为前提,除了你手动的添加文件之外,还要有效地给Magento指明你新增加的类的文件定义信息。在每一个Magento的模块里面都有一个config.xml的配置文件,这个文件

里面包含了这个模块的很多重要信息。在Magento运行时,全部模块的config.xml文件会被整合成一个很大的xml文件。

例如,如果你要用到一个新的模型,你要先在config.xml声明一下你的模型的信息,告诉magento它的模块是哪一个,它的父目录在哪里

<models>
     <
packagename>
          
Packagename_Modulename_Model
    <
packagename>
< /models>

模型要声明,新增的其它Magento组件也要声明,如助手(helper), 块(Blocks), 路由(Routes),事件(Event)。。。基本上每次你要增加新功能或做改动,都会涉及到配置文件。



控制器

在大多数的PHP系统中,程序的入口通常会是一个PHP文件,Magento也一样,而且入口也是index.php。

然而,你写的代码并不是直接放到index.php这个文件中。在MVC系统中,index.php文件里面的代码所做的事情通常是以下几点:


  1. 检查地址栏里面的URL
  2. 根据预先定义好的规则,把这个URL解释/匹配到一个控制器类和一个Action方法,这个功能常称为路由。
  3. 为这个控制器类生成一个实体,并调用执行这个方法($controller->actionMethod(),这点常称为指派。


这样,实际上,程序的入口由index.php变成了一个控制器的文件,以下面这个url为例:


http://example.com/catalog/category/view/id/25
这个URL经过解释后,分成了几块:


Front Namecatalog(前端名字)

第一块为前端名字,这个名字告诉了Magento应该在哪个模块里面找这个控制器文件。对应的模块文件应该是:

app/code/core/Mage/Catalog

Controller Namecategory(控制器)


这一块信息告诉了Magento该去找哪一个控制器,因为模块里面有一个指定的 controllers 文件夹,里面包含有多个控制器。这样Magento便找到了对应的控制器文件:

app/code/core/Mage/Catalog/controllers/CategoryController.php

里面的代码情况:

class Mage_Catalog_CategoryController extends Mage_Core_Controller_Front_Action
{
}

Magento里面的所有控制器都继承了 Mage_Core_Controller_Front_Action。

Action Name - view(执行的方法)

第三块的信息告诉了Magento该执行控制器里面的哪一个方法。因为一个控制器里面有多个方法。在这个例子里,view是应该要执行的方法。

class Mage_Catalog_CategoryController extends Mage_Core_Controller_Front_Action
{
    
public function viewAction()
    
{
        
//main entry point
    
}
}

熟悉Zend Framework的人会知道这个里命名规则。

Parameter/Value - id/25(参数名/参数值)

URL里面,在aciton名字后面的所有字符串,都会被认为是URL参数对,形式为: 键/值。通常这些URL参数可以通过GET的方法来获取得到。在这个例子里面,我们便可以通过GET的方法来

获得一个以 id 为名,值为25的参数。


要使模块里面的控制器生效,你必须在confi.xml文件里面做配置来声明它。以下这段配置文件声明了Catalog模块里面的控制器。

<frontend>
    <
routers>
        <
catalog>
            
standard< /use>
            <
args>
                <
module>Mage_Catalog< /module>
                <
frontName>catalog< /frontName>
            args>
        catalog>
    routers>
< /
frontend>

细节的地方可以慢慢考究,这里先点出这段:catalog< /frontName>

正是这段声明,把一个前端名字和模块联系了起来。Magento知道了前端名字便能找到对应的模块,进而找到控制器所在的文件夹。大多数的magento模块把前端名字取和模块一样的名字,但这个是可以不相同的。

多路由器

这里说的路由器并不是家里面买的那种路由器!

Magento通过分析URL而找到相应的控制器和执行方法的过程称为路由。这里面就包含了定义路由规则和分析逻辑,这些逻辑通常都被封装放在一个类里面,这些类就是路由器(Router

上面分析例子中提到的路由过程,被称为前端路由(Frontend)。如果Magento经过分析URL之后找不到对应的 控制器/执行方法, 那它就会进行第二次URL分析,这一次用的规则就不是前端路由的规则了,而是用后台(Admin)的

路由规则来分析当前的URL,如果用后台的路由规则也找不到对应的 控制器/执行方法,那Magento就用一个特殊的控制器来执行:Mage_Cms_IndexController.

这个CMS控制器检查Magento的内容管理系统里面是否有对应的内容要用来加载,有则加载这部分的内容,否则显示一个404的错误提示页面。

举个例子,Magento首页的INDEX页面用的就是一个CMS控制器。很多初接触Magento的人就摘不清首页用的是哪个控制器。


以URI形式定义的类加载方式

当程序的入口确定之后,PHP便开始在控制器的方法里面运行。这时候若要做点真正的事情,则需要实例化类。Magento有它自己的方式让你去实例化一个类,包括模型(Model),助手(Helper)和块(Block)。在全局性的Mage 类下面有


静态的工厂模式方法,专为实例化类而用。例如:

Mage::getModel('catalog/product');
Mage::helper('catalog/product');

这里的字符串'catalog/product'通常被称为 [分组的类](Grouped Class Name)或者称作 [全局资源标志](URI),这里的资源标志用斜杠(/)分成两部分,前面是 catalog,这一块通常是用来匹配模块,Magento用它来找到相对应的模块,这里对应 的模块是:(Mage/Catalog);后面的一部分是 product, Magento用这个信息来匹配模型,用它来找到在该模块下面的模型。

在上面的两行代码中,'catalog' 匹配的模块是: app/code/core/Mage/Catalog,也就意味着要找的类名前辍为:Mage_Catalog

把标志符后面的一部分 product 加到类名的前辍去就是:

Mage::getModel('catalog/product');
Mage_Catalog_Model_Product

Mage
::helper('catalog/product');
Mage_Catalog_Helper_Product

若要通过全局资源标志的方式去实例化类,就必须在模块的config.xml文件里面定义好规则,这样可以让Magento在运行时找到对应的类。

Magento的模型

Magento像许多其它框架一样,提供了一个对象模型映射(ORM)系统。通过ORM系统可以让开发者少写或不写SQL语句,仅通过PHP的类代码便可以控制数据源。例如:


$model Mage::getModel('catalog/product')->load(27);
$price $model->getPrice();
$price += 5;
$model->setPrice($price)->setSku('SK83293432');
$model->save();

在上面的这几行代码中,我们在Product模型上用了 "getPrice" "setPrice" 两个方法。Product模型对应的类为 Mage_Catalog_Model_Product ,然而在这个类里面并没有定义这两个方法,它的父类也没有给出这两个方法的定义,Magento这样也不会报错?!这是因为Magento的模型影射系统用了PHP的魔术方法: __call,实现了 getter和setter的功能。

调用 $product->getPrice();  “得到”了模型的“price”属性的值; 
调用 $product->setPrice();  “设定”了模型的“price”属性的值;
这两个动作的前提是product这个模型先前没有定义好getPrice和setPrice这两个方法,如果这两个方法已经定义了,则影射模型里面的魔术方法就不会调用。具体的细节在 Varien_Object 这个类里面,Magento里面的全部模型类都继承了Varien_Object。

如果要取得一个模型的全部属性和属性对应的值,可以通过getData()方法,$product->getData(),该方法返回了一个数组,里面包含的是一个模型的全部属性数据。

Magento的模型里面可以连续调用多个方法,如:$model->setPrice($price)->setSku('SK83293432'); 这是因为这几个set方法的返回值都是该模型本身的实例。Magento里面很多地方都用了这种连续调用方式。












欢迎信息反馈 / 咨询 / 评论 / 联系我们
名字   *
Email*
验证码   *
内容*