Fork me on GitHub

vanilla开发者入门教程(一)Vanilla与MVC

edited 2013年04月22日 经验心得

今天看到@winson吐槽,我觉得有些同学的确是需要指引一下了
(本篇教程假设读者已经具备了PHP面向对象的基本知识,知道类、对象、方法、继承等基本概念)

目录:
1. 认识MVC
2. VanillaForums的MVC
3. Vanilla中的控制器(controller)
4. Vanilla中的视图(view)
4. Vanilla中的模型(model)

1. 认识MVC

MVC是web开发者和桌面、移动app开发者必知必会的模式。
MVC即模型-视图-控制器,是一种将应用程序的数据层、逻辑层和表现层进行分离的方法。
image
就PHP来说,绝大多数PHP框架都是MVC架构的,包括CodeIgniter、Zend Framework、Yii,国内的ThinkPHP、QeePHP等等,Vanilla也不例外(Vanilla的内核框架叫做Garden)

模型 (Model) 代表你的数据结构。通常来说,一个模型包装了对某类数据的读写操作和领域逻辑。

视图 (View) 是一个网页的模板,也可以是一个页面片段,如页头、页尾。它还可以是一个 RSS 模板,或任何其它类型的“页面”。

控制器 (Controller) 是模型、视图以及其他任何处理 HTTP 请求所必须的资源之间的中介。详细来说,控制器接应HTTP请求,然后向模型请求需要的数据,然后调出把数据“塞进”某个视图,生成最终传递给用户的HTML

2. VanillaForums的MVC

vanilla的目录结构:
vanilla的目录结构
文件目录我简单介绍下吧

applications: vanilla的主要程序逻辑都在这里。applications的每个子文件夹都是一个功能相对独立的应用,或者称作模块,比如conversations是vanilla中的‘站内信’应用,dashboard包含的是vanilla的最基础功能(比如用户管理)和后台,vanilla文件夹中则包含论坛的功能,skeleton其实是一个空应用,它是一个应用模板,帮助你制作自己的应用。
applications文件夹中的每一个应用都是比较标准的MVC结构,每个应用中你都可以看到models、controllers、views三个文件夹

cache: 存放缓存文件

conf: 存放配置文件

js: 存放所有的javascript核心类库。

library: 存放类库,core是核心类库,即garden所在,database你懂得,vendors里放的是第三方的类库

locales: 存放本地化文件

plugins: 插件文件夹。有了插件机制你就可以在不改变任何既有代码的前提下增加或者改变功能

themes: 主题文件夹。主题其实是一套视图、css和图片,主题里的视图将覆盖应用(模块)中的视图文件,有了主题化机制,你就可以在不改变既有代码的前提下改变、覆盖原有的html结构和样式、图片

3. Vanilla中的控制器(controller)

vanilla是如何利用controller来处理用户发送来的HTTP请求呢?
假设用户点击了/discussion/4/vanilla资源集合 这个链接,负责处理这个请求的将是 applications/vanilla/controllers/class.discussioncontroller.php 这个控制器类的index函数

vanilla默认的解析规则是这样的:[/application]/controller[/method[.json|.xml]]/argn|argn=valn

在上面的例子中,/discussion/4/vanilla资源集合 这个url其实省去了'/vanilla'这样的应用目录,即上述规则中的[/application],如果输入 /vanilla/discussion/4/vanilla资源集合 这样的路径,效果是相同的。
那么在 /discussion/4/vanilla资源集合 这样的路径中,‘discussion’显然是不能省的,它对应规则中的controller,即控制器名称
而 [/method[.json|.xml]] 这部分是方法名和格式后缀 ,省略的时候,将访问默认的方法index
所以说,如果把 /discussion/4/vanilla资源集合 这个链接写全,就是 /vanilla/discussion/index/4/vanilla资源集合

规则的最后是参数,'/4/vanilla资源集合' 将被解析为index方法的参数,
public function Index($DiscussionID = '', $DiscussionStub = '', $Page = '') {
相当于 $DiscussionID = '4' ,$DiscussionStub = 'vanilla资源集合'

综上所述,访问某个应用/模块里某个控制器的方法时,应用名称可以省略,控制器名称必须要写,方法名为index时可以省略,剩下的将依次作为方法的参数

4. Vanilla中的视图(view)

我们已经在上一段落中了解到了如何根据url找到处理该请求的控制器类及方法,那么大家已经可以自行研究自己感兴趣的代码了。

作为例子,我们仍然来看DiscussionController的Index方法。既然是要研究视图,我们重点来看控制器和视图是如何交互的:

控制器最基本的方法有两个:一个是SetData,一个是Render。

SetData方法用来在控制器里给视图传递参数,比如控制器中我使用了$this->SetData('message','hello world'); 那么在视图中我调用<?php echo $this->Data('message') ?> 即可把message的内容'hello world'显示出来

Render方法用来渲染视图,大多数控制器方法的末尾都会调用$this->render(),在默认的情况下,render方法寻找视图文件的途径是这样的,在当前应用文件夹的views文件夹中,寻找与当前控制器同名的文件夹,再找与控制器方法同名的文件(暂时不讨论主题覆盖默认视图的情况)。举例来说,在DiscussionController的Index方法中执行Render()时,将获取views/discussion/index.php 作为视图。Render方法也可以指定某个视图文件来渲染,$this->Render('Blank', 'Utility', 'Dashboard'); 将渲染 applications/dashboard/views/utility/blank.php文件。

我们接着来看视图文件, 这里需要注意这句
include $this->FetchViewLocation('helper_functions', 'discussion');
它加载了同目录下的helper_functions.php文件,这是vanilla的惯用法,它把很多可能重用的视图逻辑封装于此。这可能是很多让新手头疼的地方,往往因为忽略了helper_functions文件而找不到执行某段逻辑的代码

5. Vanilla中的模型(Model)

模型实际上是实现了ORM/ActiveRecord模式,绝大多数与数据库打交道的代码都封装在Model中,而且基本上每个Model对应一张数据库表,例如DiscussionModel对应GDN_Discussion表,Controller中较少会直接操作数据库,通常是调用特定Model的方法来获取数据。

模型类文件都放在应用文件夹的models文件夹中。ORM/ActiveRecord的用法三言两语没办法说清楚,其实现成的模型用起来是很方便的,只管调用就行,ActiveRecord就是为了把繁杂的数据库操作和领域逻辑封装起来,只提供简单的接口方法供你使用!


vanilla程序的基本架构就讲到这里,大家有什么问题就在下面提问吧

此后我将介绍vanilla的扩展机制以及插件和主题的开发方法

此话题使用的标签:

回复

登录注册 才能回复。