Model-View-Controller(MVC)架构可以追溯到SmallTalk和XeroxParc。从那时起,就有很多系统描述他们自己的MVC架构。每个系统都略有不同,但是总体的目标都是把数据存储,业务逻辑和用户结构彼此分割。
大部分的PHP MVC架构大致如下
1. URL解析,通常叫做Front Controller
2. 解析后,获得controller名字和对应的方法(这个过程也被叫做routing)
3. 把对应controller初始化
4. 找到匹配的方法,并执行
5. 该方法根据请求的变量调用对应model的方法,
6. 该方法同样也会准备好回传的信息结构,并把它传给view
7. view部分会渲染HTML,用得到的信息在页面需要的地方展示。
这种模式比一开始的“每个php文件都是一个网页”要优越不少。但是对一些软件工程师来说,这仍旧是一个梦靥。下面是一些常见的抱怨
1. FrontController PHP 文件仍旧是在全局命名空间下操作
2. 惯例比配置缺少模块化
2.1 URL 的routing会缺少变化
2.2 Controlls会跟view绑的比较死
2.3 即使系统提供了重写,惯例导致了应用很难在没有大量重复代码的情况下,构建model,view或者controller
正如你可能猜到那样,magento的开发团队有这样的观点,所以用了更加抽象的MVC模式。
1. 一个单独的php文件来解析URL。
2. 这个php文件实例化Magento应用
3. Magento应用实例化FrontController对象
4. Front Controller对象实例化定义在全局配置文件里的Router对象
5. Routers检查URL是否匹配
6. 如果匹配,得到相应的ActionController和方法
7. 实例化ActionController,调用所请求的方法
8. 这个方法会实例化,并调用请求相对应的模型
9. Action Controller将会实例化Layout对象
10. Layout对象会根据请求变量和系统属性(也就是handles),创建该请求用到的Block对象们
11. Layout同样会调用Block的输出方法,这些方法内置了渲染
12. 每个block都有一个对应的template文件。Block包含了PHP 逻辑,template包含了Html和php代码
13. Blocks会直接找Data来得到数据。换句话说,Action Controller不会把数据传给Blocks。
最终我们会涉及到所有的部分,不过目前我们先看FrontController->Routers->Action Controller部分。
了解了基本理论后,我们可以进入实战了。我们将会做
1. 创建一个Hello World 模块
2. 配置该模块,并给出路由
3. 创建该模块的行为
首先安装之前做的,创建目录结构
app/code/local/XStarX/Helloworld/Block
app/code/local/XStarX/Helloworld/controllers
app/code/local/XStarX/Helloworld/etc
app/code/local/XStarX/Helloworld/Helper
app/code/local/XStarX/Helloworld/Model
app/code/local/XStarX/Helloworld/sql
然后创建配置文件 …/etc/config.xml
并增加激活改模块的配置文件app/etc/modules/XStarX_Helloworld.xml
最后确认能在admin里模块管理里看到它的存在。
1. 清楚缓存
2. Admin->System->Configuration->Advanced
3. 展开Disable Modules Output
4. 确保XStarX_Helloworld 出现
一个route是把URL转化成ActionController和调用其方法的关键。不像其他的php MVC系统,你需要自己显式定义路径,在config.xml文件里(记住,它会被加载到全局的config文件中的)
…
…
我们这里遇到了很多新的术语
什么是
为什么需要
在计算机科学界有句著名的名言,来自Phil Karlton
“在计算机科学里只有两个事情最难:cache有效性和命名物品”
Magento同样对命名也很头疼。你会在系统里,全局配置文件里有大量不直接或者很含糊不清的名字。此处就是类似的问题。有时
什么是
当router解析URL时,会做如下分割
http://localhost/magento/frontName/actionControllerName/actionMethod/
因此,在
http://localhost/magento/helloworld/*
很多magento的新手会对FrontController对象和frontName感到费解。他们实际上不是同样的东西。frontName仅仅是用来routing。
这个标签通常是模块名字的小写。我们模型的名字是Helloworld,所以标签的名字就是helloworld。
同样的frontName可以和module名字一样。这个是潜规则,但不是强制规则。事实上,一个module可能会定义多个
这个模块标签是模块名字的全名,包含了package/namespace. 这是用来定位我们的controller文件的。
最后一步就是创建Action controller了。建立
…/XStarX/Helloworld/controllers/IndexController.php
里面添加下面的代码
classXStarX_Helloworld_IndexController extends Mage_Core_Controller_Front_Action{
public functionindexAction() {
echo ‘Hello World!’;
}
}
清除缓存,载入URL: http://localhost/helloworld/index/index
或者 http://localhost/helloworld/index http://localhost/helloworld/
这时我们可以看到一个空白页面上有”HelloWorld!”。这样我们就建好第一个magento controller。
Action Controller会如何执行?
Action Controller会放在module目录下面的controllers目录里。这就是magento查找它的地方。
Action Controller如何命名?
Action Controller的名字命名如下
1. 以config.xml里定义名字串开始XStarX_Helloworld
2. 后面跟着下划线 XStarX_Helloworld_
3. 跟着Action Controller的名字XStarX_Helloworld_Index
4. 最后跟上单词“Controller” XStarX_Helloworld_IndexController
所有的Action Controller需要Mage_Core_Controller_Front_Action作为父类。
Index/index没有作用?
之前描述过请求url为:http://localhost/magento/frontName/actionControllerName/actionMethod
因此url: http://localhost/magento/helloworld/index/index
helloworld 是frontName,第一个index是actionControllerName,第二个index是方法(命名规则是 public function indexAction(){…})。
如果URL是不完整的,magento会用index作为默认,这也是为什么下面两个url等价
http://localhost/magento/helloworld/index
http://localhost/magento/helloworld/
如果我们有一个URL是这样 http://localhost/magento/checkout/cart/add
magento会怎么做呢
1. 首先查找全局配置文件,找到frontName(Mage_Checkout)对应的module
2. 查找cartAction Controller ( Mage_Checkout_CartController )
3. 调用cartAction Controller 下面的addAction方法。
其他Action Controller技巧
在我们的Action Controller里增加一个非默认方法
public functiongoogbyeAction()
{
echo “Goodbye World!”;
}
访问下面的URL来验证结果
http://localhost/magento/helloworld/index/goodbye/
因为我们会扩展Mage_Core_Controller_Front_Action类,我们会有一些父类方法。例如URL的参数部分会被解析为Key/Value对。在我们的Action Controller里增加如下方法
public functionparamsAction()
{
echo ‘
foreach($this->getRequest()->getParams() as$key=>$value )
{
echo ‘
echo ‘
}
echo ‘
}
在访问下面的URL
http://localhost/magento/helloworld/index/params?foo=bar&baz=eof
我们可以看到每个参数和对应的值都被打印出来了。
最后我们看看如果想要 http://localhost/magento/helloworld/messages/goodbye运行需要什么。我们首先建一个文件 …/XStarX/Helloworld/controllers/MessageController.php
并且命名为 XStarX_Helloworld_MessagesController
然后添加方法如下
public functiongoodbyeAction()
{
echo ‘Another Goodbye!’;
}
简而言之,这就是Magento如何实现MVC的controller。比其他PHP MVC框架要复杂一些。但是凭此灵活性,你可以构建你任何想要的URL结构。