`
isiqi
  • 浏览: 16577588 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

PHP和MVC的结合思想

阅读更多

<style type="text/css"> form { display: inline } TABLE, TR, TD { font-family: HelMS Shell Dlg, vetica, Tahoma, Arial; font-size: 9pt; color: #000000 } a:link, a:visited, a:active { text-decoration: underline; color: #000000 } a:hover { text-decoration: underline; color: #FF0000 } .hlight { background-color: #E4E7DA } .dlight { background-color: #EEF2F7 } .mainbg { background-color: #ffffff } .mainfoot { background-color: #f0f0f0 } .pinned { background-color: #99C7CC } .forum1 { background-color: #F7F7F7 } .forum2 { background-color: #EEEEEE } .post1 { background-color: #f7f7f7 } .post2 { background-color: #e7e7e7 } .posthead { background-color: #f5f5f5 } .postbak { background-color: #D2D2D0 } .title { background-color: #C4DCF7 } .row1 { background-color: #FFFFFF } .row2 { background-color: #FFFFFF } .postsep { background-color: #D6DBE7; height: 1px } .signature { font-size: 11px; color: #333399 } .postdetails { font-size: 11px } .postcolor, #postcolor { font-size: 9pt; line-height: 160% } .membertitle { font-size: 10px; line-height: 150%; color: #000000 } .normalname { font-size: 12px; font-weight: bold; color: #000033; padding-bottom: 2px } .normalname a:link, .normalname a:visited, .normalname a:active { text-decoration: none; color: #666666; padding-bottom: 2px } .unreg { font-size: 11px; font-weight: bold; color: #990000 } .highlight { color: #FF0000 } .highlight a:link, .highlight a:visited, .highlight a:active { text-decoration: underline; color: #FF0000 } .highlight a:hover { text-decoration: underline } .desc { font-size: 11px; color: #434951 } .small { font-size: 11px; color: #434951 } .copyright { font-family: HelMS Shell Dlg, vetica, Tahoma, Arial; font-size: 7.5pt; line-height: 12px } .category { font-weight: bold; line-height: 150%; color: #000000; background-color: #F8F8F8 } .category a:link, #category a:visited, #category a:active { text-decoration: none; color: #000000 } .postfoot { font-weight: bold; color: #000000; height: 24px; background-color: ##D6DBE7 } .titlefoot { font-weight: bold; color: #3A4F6C; height: 24px; background-color: #F0F0F0 } .titlemedium { font-weight: bold; color: #000000; height: 30px; background-color: #D6DBE7 } .titlemedium a:link, .titlefoot a:link, .titlemedium a:visited, .titlefoot a:visited, .titlemedium a:active, .titlefoot a:active { text-decoration: none; color: #000080 } .titlemedium a:hover, .subtitle a:hover, .titlefoot a:hover { text-decoration: underline; color: #FF0000 } .maintitle { font-weight: bold; color: #FFFFFF; font-size: 12px; height: 26px } .edit { font-size: 12px } .fancyborder { border: 1px dashed #999999 } .solidborder { border: 1px solid #999999 } .maintitle a:link, .maintitle a:visited, .maintitle a:active { text-decoration: none; color: #000000 } .maintitle a:hover { text-decoration: underline } .nav { font-weight: bold; color: #000000; font-size: 8.5pt } .pagetitle { color: #4C77B6; font-size: 18px; font-weight: bold; letter-spacing: -1px; line-height: 120% } .useroptions { background-color: #598CC3; height: 25px; font-weight: bold; color: #000000 } .useroptions a:link, .useroptions a:visited,.useroptions a:active { text-decoration: none; color: #000080 } .bottomborder { border-bottom: 1px dashed #D2D2D0 } .linkthru { color: #000080; font-size: 9pt } .linkthru a:link, .linkthru a:active { text-decoration: none; color: #000000 } .linkthru a:visited { text-decoration: none; color: #000080 } .linkthru a:hover { text-decoration: underline; color: #FF0000 } #QUOTE { font-family: HelMS Shell Dlg, vetica, Arial; font-size: 12px; color: #0000A0; padding-top: 2px; padding-right: 2px; padding-bottom: 2px; padding-left: 20px } #CODE1 { padding-right: 0.5em; margin-top: 1em; font-size: 9pt; margin-bottom: 1em; margin-left: 0pt; padding-top: 0.5em; font-family: Courier New; background-color: #FFFFFF; color: #465584; border:1px solid #000000; border-left:6px solid #666666; BEHAVIOR:url(formatPhpCode.htc) } .codebuttons { background-color: #FFFFFF; border-bottom: black 1px solid; border-left: black 1px solid; border-right: black 1px solid; border-top: black 1px solid; color: #000000; font-family: Tahoma,Georgia; font-size: 11px } .forminput { font-size: 9pt; font-family: HelMS Shell Dlg, vetica, HelMS Shell Dlg, vetica, sans-serif; vertical-align: middle } .textinput { font-size: 9pt; font-family: Courier New, HelMS Shell Dlg, vetica, HelMS Shell Dlg, vetica, sans-serif; vertical-align: middle } .input { font-size: 9pt; font-family: HelMS Shell Dlg, vetica, HelMS Shell Dlg, vetica, sans-serif; vertical-align: middle } .btnStyle { background-color: #5D7790; border-width: 2; border-color: #E9E9E9; color: #FFFFFF; cursor: hand; font-family: HelMS Shell Dlg, vetica, sans-serif; font-size: 9pt } .selStyle { background-color: #FFFFFF; border-bottom: black 1px solid; border-left: black 1px solid; border-right: black 1px solid; border-top: black 1px solid; color: #000000; cursor: hand; font-family: Tahoma,Georgia; font-size: 12px } .inpStyle { background-color: #FFFFFF; border-bottom: black 1px solid; border-left: black 1px solid; border-right: black 1px solid; border-top: black 1px solid; color: #000000; font-family: Tahoma,Georgia; font-size: 12px } .member { font-family: Tahoma; color: #003063; font-size: 9px } .curpage { text-decoration: none; color: #FFFFFF; font-family: Tahoma; font-size: 9px } .page { text-decoration: none; color: #003063; font-family: Tahoma; font-size: 9px } .page:link { text-decoration: none; color: #003063; font-family: Tahoma; font-size: 9px } .page:visited { text-decoration: none; color: #003063; font-family: Tahoma; font-size: 9px } .page:active { text-decoration: none; color: #FF0000; font-family: Tahoma; font-size: 9px } .page:hover { text-decoration: none; color: #FF0000; font-family: Tahoma; font-size: 9px } .mod { text-decoration: underline; color: #000000 } .mod:link { text-decoration: underline; color: #000000 } .mod:visited { text-decoration: underline; color: #000000 } .mod:active { text-decoration: underline; color: #FF0000 } .mod:hover { text-decoration: none; color: #FF0000 }</style>我彻底摆脱 MVC 的束缚

之所以采用这么一条看上去很自大狂的标题, 目的不是要宣扬个人主义, 而是因为如果把标题的"我"去掉, 就变成我在鼓动大家不要 MVC, 那么我很可能沦为镖靶. 在某种程度上来说, MVC 确实有着积极的意义, 在我心目中 MVC 也曾经是先进的生产方法. 但是, 在 PHP-WEB 开发的世界中, 还有没有更先进的方法呢? 我是本着这个理念去思考和摸索的. 所以本文是一篇探索新路, 开拓新思维的文章, 是本着和诸君共勉的精神而写的, 请各位 MVC 的拥护者稍安毋燥, 和某著名"工业级"模板引擎的专家们不要对号入座, 先冷静地思考一下, 世界上除了模板引擎, 是否还存在更先进的开发方法?

在 Ruby on Rails 出现之前, 我并不知道 Web 开发中的 MVC 应该是什么样子. PHPE 有几篇文章倒是讨论过, 其中也有分歧. 直到我学了 RoR, 以及看了 PHP 世界中崛起的几个仿制品, 我才清楚 MVC 在 Web 开发中的样子. 一度我也认为这是极其聪明的办法. 但是最近我又琢磨出一种代替 MVC 的开发方法, 并且认为把 MVC 用在 PHP 开发上其实算不上聪明. 那么, 不论现在天天 MVC 的, 还是不太认识 MVC 的同学们, 我都先来显摆一下, 说说 Web 开发中的 MVC 是怎么一回事.

MVC 最初是从桌面应用开发中提出来的, 最先提出 MVC 的是 Smalltalk, 后来主流的 OO 开发都接受了 MVC 思想. 而 Web 开发中的 MVC 我想应该是从 Java 阵营中来的(这个我不是很确定), 这里我主要说 RoR 和 CakePHP 中的 MVC 模式, 据说它们的 MVC 模式就是从 Java 中偷来. Ruby on Rails 和 CakePHP 都是拿一个 controller 作为程序的入口, 这个 controller 会包含一个或若干个 models, 每一个 model 都是由一个独立的类实例化出来的, 大部分是 ORM 对象, 和小部分并不对应数据表, 而是用来分担一部分 controller 责任的"模型". 每一个 controller 又会有若干的 action, 每个 action 是一个函数, 分别对应一个 view, 也就是"模板". 程序的每一次执行会化为一个 url, 比如 index.php?controller=home&action=index, 这代表程序将实例化 HomeController 并执行其中的函数 index, 然后包含一个"模板"文件 index, 函数 index 则会把数据变量 set 到模板里面去, 于是我们就看到一个页面. 这一切看上去真是完美无缺, 一个 OO 狂热者必定会为它击节叫好.

但是在 Web 开发中, 特别是在 PHP-Web 开发中, MVC 真的有那么好吗?

我上面提到过, MVC 是由 Smalltalk 阵营提出, 在其它 OO 语言特别是 Java 阵营中遍地开花的. 然而 Smalltalk 和 Java 都是面向对象语言, 而 PHP 本质上是过程式语言, 过程式语言可以比面向对象式语言更加简练.

从一个 action 中把变量 set 进 view 中, MVC 模式是这么传递变量的. 当然 PHP 完全可以这么干, 但是可以更简单, 我的答案您可能会嗤之以鼻, 我的方法就是----全局变量. 从一个 OO 狂热者的角度来看, 全局变量是愚不可及的, 它总是四处破坏封装. 但是 PHP 是一种过程式的语言, 换一种角度来看, 只要代码长度总是可以控制, 全局变量和全局函数铁定比 OO 和 MVC 要省事得多. 基于"代码长度决定项目的开发和维护成本"的原则, 我决定寻找一种能代替 MVC 的模式. 下面阐述我的模式----OO 与 PO 混合仿 MVC 又看不出 MVC 的新模式.

Web 程序总是由 url 触发的, 世界上没有一只鼠标可以同时点击两个链接, 因此对同一个用户来说, Web 程序没有并发进程. 换句话说, MVC 中的同一个 controller 中的不同 action, 它们表现为两个不同的 url, 它们的执行过程是互不相干的.

假设 Web 程序的通用入口是 index.php, 我从这里开始介绍我的模式.



这是我的 index.php 中的主要部分, 其它一些琐碎代码都是围绕这个中心进行的. 我定义了 2 个重要变量 $app 和 $action, 默认值是 home 和 index. 如果用户访问网站的根目录, 就执行 ./apps/home/home_entrance.php, 接着运行 ./apps/home/index.php. 在这里 ./apps/home 整个目录代表传统 MVC 模式的整个 controller 及其所有的 views 的集合, 但是没有类, 只有一个个的子过程, 这就是"OO 与 PO 混合仿 MVC 又看不出 MVC 模式"的主要构成. home_entrance.php 是整个网站的首页入口, 比较复杂, 下面跳到另一个 url 来看看.

假设用户点击 index.php?app=admin, 进入管理页面需要登录, 我在 ./apps/admin/admin_entrance.php 中写:



这段代码等于传统 MVC 模式中 AdminController 类中的构造器, 也可以是 Rails 中的一个 before_filter, 不同之处是代码少了很多. 它的作用是把关, 影响全局变量 $action, 把不合法的访问导向 login 页面. 我也可以加入一句 $layout = 'admin', 这样页面输出也会被导向另一种风格.

下面看看 ./apps/admin/login.php



熟悉 RoR 和 Cake 的同学对代码中的两个函数 flash() 和 redirect_to() 必定不会陌生, 它们是贯穿整个项目的全局函数(我看不出有让它们从属于某个类的必要). $user = $User->new() 这一句是我的独门秘技 QiQ 做出来的一套 ORM, 用其它的 ORM, 你可以写 $user = new User, 而 $User->select() 可以是 User::select(). 比较触动某些人的神经的可能是我的 PHP/HTML 混写风格. 是的, 我是混写了, 但是我把传统 MVC 模式的 action 和对应的 view 放在一块儿, 并非混合了业务逻辑和显示逻辑, 在这里我完全看不出分离 action 和 view 的必要. 函数 login() 和 authorize_user() 是扎扎实实的子过程, 并非实现某种功能的公共库, 它们的存在仅仅是为变量提供一层命名保护.

到这里已经可以暂时打住, 相信大家完全可以看出我的意图: 我把传统上非常复杂的 MVC 完完全全给过程化了. 过程式语言并非一无是处, 根据一个简单的约定, 我就完成了 MVC 模式非常复杂的实现. Java 们看见这样简单的实现, 肯定要眼红, 谁叫 Java 没有全局变量和全局函数呢?

但是全局变量和全局函数肯定也有短处, 所以要有一些约束. 我们可以统计一下 index.php 中出现的全局变量, 计有 $app, $action, $output_content, 和 $layout, 全局函数有 flash(), flash_out() 和 redirect_to(), 这些在 action 文件中不可再用, 这与类属性和方法不可重名是一样的.

如果把一个 app 目录看作一个大的 controller 的话, 那么甚至可以把 index.php 看作这个 controller 的一部分. 这样一来就非常清晰了, 我确实在进行 MVC, 但是你看不见 controller 类, 看不见 view 文件, 它们被我完全过程化了.

总结, "OO 与 PO 混合仿 MVC 又看不出 MVC" 模式的主要优点是:

1. 代码量大幅降低, 系统复杂度大幅降低, 间接地成本大幅降低
2. action 直接和 view 结合, 清晰度大幅上升
3. 把 "controller" 拆散成许多子过程, 有利于构建大型项目.
国内网站习惯把大量内容放在首页上, 如果用传统的 MVC 模式来构建首页, 由于所有 actions 集中于一个 controller 中, 导致 controller 过度复杂(可能有数十个 action). 分拆之后每个程序员可以负责若干 action, 更有利于协同开发.
4. 如果实在需要分离 view, 可以在 index.php 中增加一句


这样就可以把 view 分离出来交给美工人员去做.

以上就是我今天的发言.

转:http://club.phpe.net/index.php?act=ST&f=15&t=12212
分享到:
评论

相关推荐

    php+MVC思想+Smarty+MYSQL后台管理系统

    这是一套完整的后台管理系统,功能大体齐全,PHP+Smarty+MYSQL,结合伪静态和MVC思想完成的系统开发,单一入口文件,工厂模式等等,值得去运用和学习。登录用户名:siyizhen 密码:x140010

    php模式MVC详细分析

    MVC模式的核心思想是分离关注点,将业务逻辑、数据处理和用户界面分别放在三个不同的组件中: 1. **Model(模型)**:主要负责与数据库交互,处理数据的增删改查操作。它封装了数据处理的细节,使得视图和控制器...

    PHP+EasyUI+MVC框架+数据库脚本+人事管理

    旨在帮助初学者了解如何利用PHP编程语言、EasyUI前端框架以及MVC(Model-View-Controller)设计模式来开发这样的系统,并结合数据库脚本来存储和处理人事数据。 首先,PHP是一种广泛使用的服务器端脚本语言,尤其...

    MVC与IOC容器互动

    总结,MVC与IOC容器的结合在Formwork框架中实现了高度的模块化和解耦,使得开发者能够更专注于业务逻辑,而不是对象的创建和管理。通过依赖注入,降低了组件间的耦合,增强了代码的可读性和可测试性,为项目的开发和...

    jsp/mvc/mysql外文文献

    在Web开发中,MySQL常与PHP、Java(包括JSP)等后端语言结合使用,为网站提供数据存储和管理功能。 在"参考文献"这个文件中,可能包含对JSP、MVC和MySQL深入研究的外文资料,如最佳实践、最新技术趋势、性能优化...

    小议MVC模式开发

    MVC(Model-View-Controller)模式是一种广泛应用于Web应用程序设计的架构模式,它的核心思想是将业务逻辑、数据处理和用户界面进行分离,以提高代码的可维护性和可扩展性。在本文中,我们将深入探讨MVC模式的组成...

    1-MVC-PHP:MVC-PHP

    MVC架构的核心思想是将应用逻辑、数据处理和用户界面分离,以便于管理和更新。具体来说: - **模型(Model)**:负责处理业务逻辑和数据管理。它与数据库交互,获取或存储数据,并确保数据的完整性和一致性。在PHP...

    萌格网,仿CI框架的使用模式,利用原生PHP构建的基于MVC架构的网站系统。.zip

    通过学习和分析萌格网的源码,学生可以深入理解PHP和MySQL的结合使用,掌握MVC架构的设计思想,以及如何构建一个完整的Web应用。这对于提升PHP编程技能,以及理解Web开发流程都是非常有帮助的。

    基于JAVA开发Web应用中MVC模式分析.pdf

    它的核心思想是将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller),每个组件负责不同的任务,实现代码逻辑、数据处理、用户交互的分离,从而提高代码的可维护性、可复用性,并简化项目架构...

    dwz+mvc开发的相册给管理系统

    【描述】:在传统的开发模式中,开发者通常会将业务逻辑、数据访问和用户界面进行分离,这就是MVC(Model-View-Controller)模式的核心思想。在这个相册管理系统中,模型层(Model)负责处理数据和业务逻辑,视图层...

    PHP实战--作者:雷勒索(Dagfinn Reiersφl) , 贝克(Marcus Baker) , 史夫利特(Chris Shiflett)

    而随着PHP 5的发布和Zend框架的应用,PHP和敏捷思想、设计模式以及单元测试的联姻成为主流话题。 《PHP实战》首先介绍了面向对象设计的原则、模式和技巧,然后讲述了如何运用PHP的语法和特性来解决Web编程中遇到的...

    《细说PHP》配套源码

    《细说PHP》配套源码全书共17章,每一章都是...最后以一个比较完整的、采用面向对象思想,以及通过MVC模式设计,并结合Smarty模板的CMS系统为案例,详细介绍了Web系统开发从设计到部署的各个细节,更好地进行开发实践。

    PHP学习总结(很不错的总结)

    这个案例展示了如何结合PHP和MySQL数据库构建一个完整的网站系统,包括需求分析、系统设计、编码实现、测试与优化等阶段,为实际项目开发提供参考。 #### 结论 PHP作为一门成熟的编程语言,不仅易于上手,而且功能...

    php版简易网上商城源码

    此外,还可能涉及到PHP框架的基础,虽然这是一个“简易”商城,但可能包含了MVC(模型-视图-控制器)架构的基本思想,这是一种常见的Web应用程序设计模式。 至于【压缩包子文件的文件名称列表】为"shop",可以推测...

    PHP和Mysql Web开发完整源代码

    《PHP和MySQL Web开发...通过这些源代码,你可以系统地学习和实践PHP与MySQL的结合应用,理解Web开发的核心原理,并提升你的编程技能。同时,这些例子也可以作为日后项目开发的参考,帮助你在实际工作中解决各种问题。

    PHP-Mini:PHP Mini 是一个轻量级强大的 PHP 框架,遵循 MVC 风格的约定

    综上所述,PHP-Mini作为一个轻量级的PHP框架,结合MVC模式,为开发者提供了一个高效、灵活的开发环境。它的特性使其在快速开发、小规模项目以及与JavaScript库协同工作时具有优势。然而,为了充分利用PHP-Mini,...

    Web标准思想

    结合Web标准思想,PHP开发应遵循以下原则: 1. MVC(Model-View-Controller)架构:这是一种常见的设计模式,将业务逻辑(Model)、用户界面(View)和数据控制(Controller)分离开来,便于代码的组织和维护。 2....

    细说PHP(第2版) - 高洛峰.mobi

    《细说PHP(第2版)》共...最后以一个比较完整的、采用面向对象思想,以及通过MVC模式设计,并结合Smarty模板,基于BroPHP框架的CMS系统为案例,详细介绍了Web系统开发从设计到部署的各个细节,便于更好地进行开发实践。

    php学习总结.pdf

    结合PHP和MySQL数据库,可以构建功能全面的Web应用。案例分析包括需求分析、系统设计、编码实现、测试与部署等环节,是学习PHP实战的重要途径。 #### 总结 从PHP的基础语法到高级框架运用,再到具体项目的实践,...

Global site tag (gtag.js) - Google Analytics