在框架盛行的今天,MVC 也不再是神话。 经常听到很多程序员讨论哪个框架好,哪个框架不好, 其实框架只是工具,没有好与不好,只有适合与不适合,适合自己的就是最好的。
每次我面试应届生时都会问他使用过什么框架,并谈谈对这些框架的理解。 当面试有经验的程序员时,会让他自己写一个框架出来。 其实也不是让他编码,只要有思路就 OK 了。 我觉得,如果一个有一年经验的程序员连一个 Framework v0.0.1 都开发不出来的话,肯定是没有深入理解一个框架。
前几天 @phoenixg 说要自己写个 MVC 框架。 而且他也确实不仅仅是说说而已,短短一个周末,这个框架雏形就神奇的出现在了github上。
这篇博文的名字是『自己动手设计PHP MVC框架』, 所以本文不会涉及太多的编码,文中出现的任何代码片段都是我直接在 vim 里面敲的, 没做任何测试,如果想使用文中代码需自行测试。
跟随本教程,将从零开始设计一个属于自己的 MVC 框架。
我使用过 ZendFramwork、CodeIgniter,每个框架都有自己的优点和不足。 在写本文之前,我又看了 Symfony、cakephp、MooPHP、doitphp 等的核心源码, 下面说说我将把我的框架设计成什么样子,这一章主要讨论 URL 的设计。
1. REST
在这个 REST 横行的时代,如果一个框架不支持 REST,肯定被前卫程序员所瞧不起,所以本框架也要支持 REST。
第一个设计准则:所有东西都是资源,资源有多种表现形式。
不管实际上存在的,还是抽象上的, 所有资源都会有一个不变的标识(ID),对资源的任何 API 操作都不应该改变资源的标识。
事实上,上面的这些完完全全是按照互联网的特性提出来的。
- 互联网中,一个 URL 就是一个资源;
- 资源的内容就是 HTML 页面;
- 不管怎么改 HTML 内容,URL 都不会改变;
- 资源之间通过 HTML 里的连接联系起来;
- 每次获取的时候,获取到的都是完整的 HTML 内容。
比如
GET http://justjavac.com/users // 所有用户
GET http://justjavac.com/users/phper // 标识为phper的用户
2. 扩展名
在此我不讨论扩展名和文件类型之间的关系,以及“扩展名只是约定,而文件类型记录在文件头”。
我通常把扩展名理解为“约定”,而不是文件类型。 当我们请求一个 news.html 时,我们并不能确信它就是一个存在于服务器上的news.html文件, 它也可能是php文件,也可能是jsp文件,在nodejs流行的今天,它也可能是一个js文件。 但不管页面是如何生成的,有一点是明确的——最终我们得到了一个html文档。
虽然rest不要求使用扩展名,但有人告诉我,如果在一个女生名字后面加一个.rmvb 的扩展名,将变得非常……因此本框架将支持扩展名,但是扩展名并是资源的一部分。
什么意思呢?
还是前面的例子,所有用户这个资源该如何表示呢? 用 urlhttp://justjavac.com/users
就可以唯一标识,
而扩展名可以用来标识资源的不同表现形式。
a、当我们请求http://justjavac.com/users
时,框架将返回一个html文档, 数据可能在表格中,也可能在
form 中,也可能在 div 中(如下图)。
b、当我们请求http://justjavac.com/user.json
时,将返回 json 格式数据。
[
{
"firstName" : "just",
"lastName" : "javac",
"userName" : "@justjavac"
},
{
"firstName" : "Tom",
"lastName" : "Cat",
"userName" : "@tomcat"
},
……
]
c、当我们请求http://justjavac.com/user.xml
时, 将返回 xml 格式的数据,xml 文档可由
DTD 或者 XSD 定义。
d、如果我们想把所有用户的列表发给管理员,或者打印出来呢?
可以直接访问http://justjavac.com/user.xls
,框架将会返回 Excel 电子表格。 当我们高高兴兴把文件下载下来,却发现电脑没有安装
Excel,怎么办? 没关系,我们还可以访问http://justjavac.com/user.jpg
,毕竟看图工具我们还是有的。
用过 Google 短网址服务的同学都知道,比如我的网站 http://justjavac.com 的短网址是http://goo.gl/JMQJ8,Google
还提供了二维码表示法,只需要在后面添加 .qr 例如http://goo.gl/JMQJ8.qr。
taourl 也提供了一个很方便的功能,例如 我们想查看网址http://taourl.com/7c1ug的访问情况,那么只需要在网址最后面添加一个+号就可以了。
总之,不管用了什么扩展名,将返回同一个资源,只是表现形式不同罢了。 这也就是经常所说的数据 + 模板 = 输出。
如果没有扩展名呢?返回 HTML 文档?
别忘了 http 请求的 Accept。 设置请求头的Accept: application/x-excel
我们依然可以得到一个电子表格。
甚至当我们访问某个用户时,http://justjavac.com/user/justjavac
,我们可以使用Accept:
text/x-vcard
,如果不知道嘛意思,自己Google去。
下面说说设计模式,在这个功能上,可以用一个适配器模式,根据不同的扩展名选择不同的适配器,执行不同的功能,最后提供相同的接口,具体实现就不多说了。
3. 多语言支持
@TODO多语言支持的 url 结构设计
4. 充分利用 HTTP
和请求有关的错误和其他重要的状态信息怎么办呢?
简单,使用 HTTP 的状态码! 通过使用 HTTP 状态码,你不需要为你的接口想出 error/success 规则,它已经为你做好。
比如:假如一个消费者提交数据(POST)到/api/users
,
- 你需要返回一个成功创建的消息,此时你可以简单的发送一个 201 状态码(201=Created)。
- 如果失败了,服务器端失败就发送一个 500(500=内部服务器错误),
- 如果请求中断就发送一个 400(400=错误请求)。
- 也许他们会尝试向一个不接受 POST 请求的接口提交数据,你就可以发送一个 501 错误(未执行)。
- 又或者你的 MySQL 服务器挂了,接口也会临时性的中断,发送一个503错误(服务不可用)。
幸运的是,你已经知道了这些,假如你想要了解更多关于状态码的资料,可以在维基百科上查找。
HTTP 支持客户端缓存,在HTTP响应里利用 Cache-Control,Expires,Last-Modified 三个头字段, 我们可以让浏览器缓存资源一段时间。
REST 也可以利用这些头,告诉客户端在一定时间内不需要再次请求资源。 这对提高性能有很大好处。Expires、Last-Modified 以及 ETag 可以通过资源的属性提供,这个在有关 Model 层的设计中再详细介绍。
5. 测试与调试
PHP 的灵活使得自动化测试或者 TDD 变得困难,至少和 Java 比就差了好大一截。 在框架中,将很自由的开启调试,比如我的设计是通过添加 url 参数:
http://justjavac.com/user/justjavac?DEBUG=2
通过添加 DEBUG 参数告诉框架开启调试模式,后面的参数值是调试的级别 level。 类似的,你也可以加入 LOG 参数来启动日志。
这样设计还有一个好处就是,不需要修改配置文件,而且还可以针对某一个页面来开启或者关闭。 当我用 CI 时,每次我发现程序中的问题,都在配置文件中将 log 级别设置为 all, 再重新打开页面,当我再看 log 文件时,居然已经几百行了,因为我访问的每个页面都被记录到了日志里面。
测试和 url 好像没有多大关系,测试放在单独的章节讨论。 我为测试约定的 url 是添加 test,比如为控制器 justjavac.controller.php 写的测试用例(Test Case)可以通过http://justjavac.com/test/user/justjavac
访问。
但我还是比较喜欢在命令行测试,毕竟当你手动点击浏览器,并手动输入 url, 手动敲回车键时,已经违背了自动化测试。
6. Ajax
@TODO应用于单页 Ajax 的 url 结构设计
分享到:
相关推荐
**20.2 PHP框架——Zend Framework** - **特性**:ZF是基于PHP5的开源框架,支持MVC架构,强化了代码组织和维护。 - **目录结构**:推荐的目录结构有助于管理和部署,但可能需要对Apache服务器有高级控制权。 - **...
**PHP MVC 开发框架——禅道PHP框架(Zen Tao PHP)** PHP,全称Hypertext Preprocessor(超文本预处理器),是一种广泛应用于Web开发的开源脚本语言,以其简单、快捷的特性深受开发者喜爱。在PHP的世界里,MVC...
【标题】"PHP实例开发源码——DoitPHP 轻量级PhP框架 MySql专业版.zip" 提供的是一个基于PHP语言的轻量级框架DoitPHP的专业版源码,结合了MySql数据库系统,适用于快速构建中小型Web应用程序。这个框架以其简洁、...
【PHP实例开发源码——ky框架.zip】是一个包含PHP编程语言的开源框架——ky框架的源代码包。这个框架可能是为了简化PHP应用开发而设计的,它提供了许多实用的功能和结构,以帮助开发者快速构建高效、可维护的Web应用...
在PHP的世界里,MVC框架如Yii、Laravel、Symfony等已经非常流行。MayFish框架可能是其中的一个新兴或特定用途的框架,它可能包含以下关键组成部分: 1. **模型(Model)**:模型负责与数据库交互,处理业务逻辑和...
【PHP实例开发源码——Xataface php网站框架生成器.zip】是一个包含PHP源代码的压缩包,主要用于演示和学习如何使用Xataface这一PHP框架来构建网站。Xataface是一个开源的工具,它允许开发者快速地为MySQL数据库创建...
JunePHP是一款基于PHP语言开发的轻量级框架,它的设计目标是提供快速、简洁和高效的开发体验。在这款框架中,开发者可以利用其强大的MVC(Model-View-Controller)架构来组织代码,提高项目的可维护性和扩展性。源码...
**PHP实例开发源码——MayFish MVCPHP开发框架** MayFish是一款基于PHP语言的MVC(Model-View-Controller)开发框架,旨在提供高效、灵活的开发环境,帮助开发者快速构建Web应用。该框架的核心设计理念是解耦合,...
【标题】"PHP实例开发源码—HerosPHP(MVC开发框架).zip" 提供的是一种基于PHP语言的MVC(Model-View-Controller)框架——HerosPHP的开发源码。MVC模式是软件工程中的一种设计模式,它将应用程序的业务逻辑、数据和...
**PHP实例开发源码——DooPHP 轻量级开源PHP开发框架** DooPHP是一款轻量级的PHP开发框架,旨在简化Web应用的构建,提高开发效率,同时保持良好的代码组织结构和可扩展性。它采用了MVC(Model-View-Controller)...
《图书管理系统源码详解——基于ThinkPHP5 MVC框架》 图书管理系统是信息技术在图书管理领域中的实际应用,它能够高效地实现图书的入库、出库、借阅、归还等操作,大大减轻了图书馆工作人员的工作负担。本系统采用...
【PHP网页设计——汽车广告】知识点详解 PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适用于Web开发。在这个“汽车广告”项目中,PHP被用来创建一个后台管理系统,以便于管理和展示汽车广告。...
3. MVC模式:大多数现代PHP框架采用MVC(Model-View-Controller)设计模式,将业务逻辑(Model)、用户界面(View)和控制流程(Controller)分离,以实现更好的可维护性和扩展性。如果"phpweb"是基于MVC的,那么...
通过研究QeePHP的源码,开发者可以学习到如何构建一个完整的PHP框架,理解MVC架构的工作原理,以及如何优化数据库交互、错误处理和性能调优等关键技能。此外,还可以了解如何利用框架来组织项目结构,提升开发效率,...
2. **MVC框架**:如Laravel、CodeIgniter或Yii,这些框架常用于构建Web应用,提供更好的代码组织和可维护性。 3. **数据库管理**:可能使用MySQL,涉及SQL语句编写、数据表设计和事务处理。 4. **RESTful API设计**...
【标题】中的“PHP实例开发源码——php打造简易个人网站系统”表明这是一个关于使用PHP编程语言构建简单个人网站系统的实际代码示例。这个项目可能是为了教学或实践目的,让学习者了解如何用PHP实现一个基础的网站...
【PHP实例开发源码——硬汉联盟家装平台 PHP版】是一个基于PHP编程语言的家装服务平台的源代码实例。这个项目提供了全面的后端和前端功能,适用于构建一个完整的在线家装服务系统,帮助用户与装修公司、设计师进行...
【PHP实例开发源码——欧式风格家具网站php源码.zip】是一个包含PHP源代码的压缩文件,主要用于构建一个展示欧式风格家具的网站。这个项目可能是为了帮助开发者学习PHP编程、Web开发以及数据库交互等技能。下面我们...
**PHP轻量级框架——CodeIgniter** 在Web开发领域,PHP是一种广泛使用的服务器端脚本语言,尤其在构建动态网站方面表现出色。对于初学者和有经验的开发者来说,选择一个合适的PHP框架能极大地提高开发效率和代码...