VC模式下,客户直接发送请求到控制器,控制器根据用户请求的资源分发到相对应的模型来处理,模型完成了业务逻辑后,把所要的数据发送到视图,视图显示返回给客户。这就是web 或是说B/S架构的MVC工作流程。
控制器:
用户的所有请求会发送到控制器,由控制器来根据需要调用模型和视图。比如用户请求index.php 控制器文件,index.php里面不会设计到任何的数据库操作、逻辑操作。它只会寻找执行用户请求的业务模型,把所有的业务逻辑操作交给模型也就是MVC中的M。把控制器独立出来,形成单入口访问模式,方便做全局管理,比如:日志记录等。
模型:
模型是业务逻辑数据的集合,比如数据库操作,复杂的逻辑运算等。按照功能或项目模块来分成一个个模型,模型间的耦合性很小有利于项目以后的扩展和修改。
视图:
Web技术中的MVC的C层。其主要是由 HTML 、XML语言组成的界面。以前的web界面是视图和模型混杂在一起使用,形成了杂乱的代码,这样使日后程序的维护十分艰难。PHP中知名的模板引擎smarty 就是为了实现模型和视图分离的一种技术。现在smarty 在PHP行业中被开发者广泛使用。
MVC思想不是为了某种语言而设计的,它适用于所有的面向对象的语言。比如知名的实现MVC思想的JAVA语言的 Struts 框架。当然PHP 框架也是百花齐放如 :Zend Framework 、 Fleaphp 、Thinkphp 、Cakephp 等,都能很好的实现MVC思想而且他们大量应用了GOF 设计模式,开发人员如果基于以上几种MVC框架来进行项目开发的话,开发的效率和代码质量都会大幅度提升,特别是多人协作开发的项目。那PHP怎么实现MVC的呢?下面给大家开发一个简单的MVC基础框架来说明这一点,完整代码附光盘09/20。
类驱动
在php5中可以使用__autoload 函数来实现类自动加载。但单纯这样的方式不够灵活的。比如类文件存放在不同的目录里面,而此时又需要自动加载的情况下,我们就需要在__autoload函数里进行复杂的逻辑判断来实现自动加载。
比如需要实例化两个类:Myblog 、Mybook。Mylog类在根目录下的Lib/test.php 文件里,Mybook类在根目录下的App/command.php 文件里。
__autoload
复制PHP内容到剪贴板
PHP代码:
函数里实现加载:
[php]<?php
function __autoload($class){
if($class =='Myblog') include 'Lib/test.php';
if($class =='Mybook') include 'App/command.php';
if(!include_once($classpath)){//加栽类
throw newException("加载类库失败");
}
}
?>
这只是实例化两个不同目录下的两个类而已。如果项目中使用面向对象开发的话,类不会那么少,大家可以想像一下。如果要加载数个不同目录下的类,在__autoload函数里实现会是多么的麻烦和不灵活。
在这里给出个比较简单的解决方案,而且这个解决方案在很多MVC框架中都得以很好的应用
我们只需要在类的命名方式上做些改变,以类的目录路径为类名:
/Yhmphp/ App.php 里的Mysession类,命名为:Yhmphp_App_Mysession。用‘ _ ’下划线来替换
路径分割符,以相对路径下的目录路径做类名。
又比如根目录下的Lib目录下test.php 文件里面(/Lib/test.php) 有个Myblog 类,可以这样给Myblog类命名:
复制PHP内容到剪贴板
PHP代码:
<?php
class Lib_Myblog{}
?>
实例化Lib_Myblog类:
<?php
$myblog = newLib_Myblog;
?>
__autoload函数里用str_replace函数把路径分割符替换类名中的‘ _ ’下划线,这样就可以准确的找到Lib_Myblog类的所在文件的路径然后准确的加载了:
复制PHP内容到剪贴板
PHP代码:
<?php
function __autoload($class){
$classpath =str_replace('_','/',$class).'.php';
if(!include_once($classpath)){//加栽类
throw newException("加载类库失败");
}
}
?>
模型的路由:
当我们给单入口文件(控制器)index.php
加上了模型选参m(index.php?m=myblog),控制器就会去寻找 myblog模型类,并实例化,然后执行myblog模型类中的 model 方法,最后执行show方法
来显示视图。
复制PHP内容到剪贴板
PHP代码:
<?php
class App_Run
{
publicfunction routing(){
$model =MOBILE_MODEL.'_'.MODEL_SWITCHING.'_'.$_REQUEST['m'];
if(class_exists($model)){
$cake= new $model;
method_exists($cake,'model')&& $cake->model(); //执行模型里面的 model方法
method_exists($cake,’show’)&& $cake->show(); //视图层
}else{
thrownew Exception("数据模型不存在");
}
}
}
?>
常量MBILE_MODEL定义了模型存放的目录名,在这里做了定义方便日后模型目录的更改。这是个良好的习惯。能统一定义的信息就该统一。能模块化的业务逻辑就应该模块化。为日后的项目维护和项目扩展做好铺垫。
MBILE_MODEL
复制PHP内容到剪贴板
PHP代码:
在Config/__Active.php文件里面这样定义:
[php]<?php
/**
系统配置
*/
define('MOBILE_ROOT', ''); //站根目录
define('MOBILE_MODEL','Modules'); //模型目录名
?>
class_exists() 函数来判断客户请求的($_REQUEST['m']) 模型类是否存在。Class_exists() 方法依据__autoload() 函数来加载判断。所以__autoload()函数必须在class_exists() 方法之前先加载。
模型类如果存在,就使用method_exists() 方法来判断执行模型类里面的model 方法里面的业务逻辑,然后再执行show() 方法显示视图。这样就完成了一个 MVC 流程。
存放模型的目录是 Modules 目录。这个在上面的MOBILE_MODEL常量中已经定义。难道所有的业务模型都存在一个Modules目录里面吗?这样的设计的确有点问题。文件夹里面的文件过多,损耗程序寻找模型加载的时间,而且模型过多存在一个目录之中,会让这个项目变得很杂乱。比如前台和后台的模型目录和视图目录就应该分开存放。
复制PHP内容到剪贴板
PHP代码:
<?php
/**
多模型目录
*/
if(empty($_GET['c']) && ) $_GET['c'] ='Default';
if(empty($_GET['m'])) $_GET['m'] = 'Index';
define ('MODEL_SWITCHING',$_GET['c']) ; //前台后台目录切换
?>
常量MODEL_SWITCHING 就是为解决这个问题设计的:
我们先看最后一句代码:
复制PHP内容到剪贴板
PHP代码:
define('MODEL_SWITCHING',$_GET['c']) ; //[font=宋体]
前台后台目录切换[/font]
它定义了常量MODEL_SWITCHING 以$_GET ['c']变量为值。App_Run 类中,常量MOBILE_MODEL 、MODEL_SWITCHING 和$_GET['m'] 组成了模型的加载路径:
$model = MOBILE_MODEL.'_'.MODEL_SWITCHING.'_'.$_GET['m'];
这样设计以后我们想添加多个模型目录都是很容易的事情了。比如:项目需要添加两个模型目录。前台模型目录:Default 和 后台模型目录:Admin 。只需要在默认的模型目录 Modules 下创建 Default 和Admin 两个目录,然后客户访问的URL 中 添加一个 参数c :
访问Default 目录下的Myblog业务模型: index.php?c=default&m=myblog
访问Admin 目录下的Member业务模型: index.php?c=admin&m=member
我们可以再设计灵活及人性化点,就是当$_GET[‘m’]和$_GET[‘c’] 客户没有设置的时候来给模型目录和业务模型类设置一个默认值。
if(empty($_GET['c'])
) $_GET['c'] = 'Default';
if(empty($_GET['m'])) $_GET['m'] = 'Index';
控制器
PHP MVC典型的设计就是使用单入口php文件来实现MVC中的C:控制器。所有的客户请求全部经过index.php 控制器集中控制。然后按需进行分发:
复制PHP内容到剪贴板
PHP代码:
<?php
/**
入口文件
*/
try{
error_reporting(E_ALL);//关闭错误输出
require'Config/__Homeswitching.php';
require'Config/__Active.php';
require'App/Auto.php';
$set = newApp_Run;
$set->routing();
}catch (Exception $e){
echo($e->getMessage());
}
?>
多模型设置文件:__Homeswitching.php,定义基础模型目录文件:__Active.php,类驱动文件:Auto.php
加载完后,再实例化模型路由App_Run类,执行其 routing() 方法 寻找完成客户请求。
业务模型
业务模型类是整个项目中使用最多的。它就是MVC 中的M (模型)。类里面封装了大量的业务逻辑。比如:客户向index.php 控制器 请求 (index.php?m=newbook)newbook业务模型,来查询最新出的图书。 那么newbook业务模型类所需要完成的任务就是查询数据库,从数据库中提取最新的图书资料,然后发送到视图层(View)显示给客户。显然,MVC 模式可以把 模型与模型、功能与功能之间的耦合度变得很小、扩展性很强。
复制PHP内容到剪贴板
PHP代码:
<?php
/**
* 模型类
* */
class Modules_Default_Index
extends App_Manage
{
privatenewbook=’’;
publicfunction __construct(){
parent::__construct();
}
publicfunction show(){
$this->tpl->assign(‘newbook’,$this->newbook);
$this->tpl->display('Index');
}
publicfunction model(){
/**实现业务逻辑*/
$this->newbook = ‘PHP MVC’;
}
}
?>
业务模型类里面有两个主要方法: model() 、show() 方法。Model() 方法主要实现业务逻辑,比如:读数据库、写数据库等。Show() 方法主要和model() 方法联系获取业务逻辑的数据,然后输出给视图(php模板)。
读者请思考下以下几个问题:
模型类 Modules_Default_Index 为什么要起这个名字?前面__autoload讲解中已讲解。Show() 方法是否能去掉只实现model() 模型?模型的路由小节中讲解。
全局类
在项目开发里,有很多我们自己封装好的类:数据库操作类、模板类、email发送类、分页类、文本缓存类、内存缓存类memcache等等。这些类中有些是每个模型都必须加载使用的,比如 数据库操作类、分页类。难道我们每个模型里都要显式的实例化一次?那真是太麻烦了。所以设计一个全局管理类App_Manage :
复制PHP内容到剪贴板
PHP代码:
<?php
class App_Manage{
protected$tpl;
protected$mem;
protected$email;
publicfunction __construct(){
$this->tpl = new Lib_Tpl;
/*
$this->mem = new Lib_Memcached;
$this->email= new Lib_Mailer();*/
}
[font=宋体]}[/font]
[font=宋体]
?>[/font]
在App_Manage中。我们简单的在其构造方法中实例化了几个常用的类。每个模型都继承App_Manage类,这样模型类里面就可以使用父类的方法和属性,以此实现全局类:
复制PHP内容到剪贴板
PHP代码:
public function __construct(){
parent::__construct();
}
分享到:
相关推荐
大家好,我是一位20岁的自学C# MVC开发者。在过去的两年里,我通过自学和实践,深入掌握了C#语言和MVC框架。...无论你是初学者还是有一定经验的开发者,本资源都将为你提供全面的MVC框架学习体验。
首先,我会介绍MVC框架的基本概念和优势,让读者了解MVC框架的重要性和应用场景。然后,我会详细介绍MVC框架的核心元素,包括模型、视图和控制器,以及它们之间的关系和作用。接下来,我会通过具体的示例和练习,让...
https://blog.csdn.net/weixin_39934453/article/details/132242216PHP傻瓜也能搭建自己框架,手把手搭建一个mvc框架PHP最简单自定义自己的框架(一) PHP最简单自定义自己的框架创建目录结构(二) PHP最简单自定义...
Struts是一个开源的MVC框架,负责处理用户请求并展示视图。它通过Action类来控制业务流程,使用ActionForm对象传递请求参数,同时提供了一套强大的标签库简化JSP页面的编写。在SSH集成中,Struts主要作为前端控制器...
Java编程的学习,一直以来都是一门非常重量级的学习科目,本教程以项目实战为导向,帮助广大学员手把手教学,本课程从无到有,循序渐进的手写mvc框架,由于官方的框架比较复杂,为了让同学们能够学懂,先从简单地MVC...
总结来说,通过SSH框架实现留言板功能,涉及到的主要技术点包括:项目结构设置、数据库连接配置、Spring和Hibernate的集成、MVC模式的应用以及实体类和数据库表的映射。通过这个过程,开发者可以深入理解SSH框架的...
Struts提供了MVC设计模式的实现,Spring则负责管理对象及其依赖关系,而Hibernate则是用于简化数据库交互的ORM(对象关系映射)工具。本教程将详细讲解如何在Myeclipse环境下搭建SSH框架。 首先,创建一个新的Web ...
本教程以项目实战为导向,帮助广大学员手把手教学,本课程从无到有,循序渐进的手写mvc框架,由于官方的框架比较复杂,为了让同学们能够学懂,先从简单地IOC框架入手,然后不断地升级和迭代,逐渐成为官方比较接近的...
Spring MVC 是一个强大的Java web应用程序框架,用于构建...随着项目规模的扩大,你可能还需要配置更多的组件,如拦截器、过滤器、数据绑定、国际化等,但这个最小化配置已经足够让你开始理解和使用Spring MVC框架。
之前上传的资料没有加入建设步骤word文档,因此重新传了一次,本次资料包括:asp.net mvc3框架实例,c#语言,word文档讲述一步步写代码,手把手教,程序案例步骤文档也程序代码齐全,没有基础也可以学.
- 右击项目,选择Myeclipse -> Add Struts Capabilities…,设置基础包名,添加Struts框架。 5. **添加Spring支持** - 右击项目,选择Myeclipse -> Add Spring Capabilities…,选择所需Spring库文件,将其添加到...
它作为Spring框架的一部分,提供了模型-视图-控制器(MVC)架构模式的实现,简化了后端开发流程。下面将详细介绍SpringMVC的基本概念、搭建过程及重要组件。 1. **SpringMVC基本概念** - **MVC架构**:MVC是一种...
《手把手教你SSM整合》是一份详细的教程,旨在帮助初学者或开发者了解如何将Spring、Spring MVC和Mybatis这三大主流Java框架整合在一起,构建一个完整的Web应用程序。以下是对这个整合过程的详细阐述。 首先,...
你需要学习如何在J2EE中实现MVC,如使用Struts或Spring MVC框架。 4. **EJB(Enterprise JavaBeans)**:EJB提供了一种标准的方式来创建可部署的、事务管理的、安全的和可伸缩的企业级组件。包括会话bean、实体bean...
标题中的“一个简单的手把手教你写购物车的PDF文件”表明这是一个教程性质的文档,旨在指导读者如何构建一个基础的购物车系统。购物车是电子商务网站的核心功能之一,它允许用户选择并存储他们想要购买的商品,直到...
SpringMVC、Spring和MyBatis是Java Web开发中非常流行的三大框架,它们共同构建了SSM(Spring MVC + Spring + MyBatis)框架体系,为开发者提供了强大的后端服务支持。下面将详细介绍这三个框架的核心概念、整合过程...
SSH入门教程:手把手教你整合Struts1.2、Spring和Hibernate SSH是Java开发中的一个经典技术栈,由Struts、Spring和Hibernate三个开源框架组成。本教程将引导初学者逐步了解并掌握这三个框架的整合,从而实现一个...
在这个“手把手教你做ASP.NET留言本”的教程中,我们将探讨如何使用ASP.NET和Visual Studio .NET 2005创建一个简单的留言本应用。 首先,确保你的开发环境准备就绪。你需要一台运行Windows 2000或更高版本的计算机...
本文旨在手把手教你如何入门 Struts2,通过实际操作来理解其核心概念和配置过程。 首先,我们来看一下 Struts2 的优点和它解决的问题。Struts2 作为 MVC 2 模型的框架,提供了丰富的功能,比如一个完整的标签库...
以上就是关于“手把手教你,Spring定时发送邮件”的主要知识点。通过学习和实践,你不仅可以掌握Spring的定时任务,还能熟练运用JavaMailSender发送邮件,从而提升你的系统自动化水平。在阅读给定的博文链接...