php MVC 及例子解释

时间:2021-02-01 03:10:02
根据http://www.21ds.net/article/4/453改写: 

MVC模式在网站架构中十分常见。它允许我们建立一个三层结构的应用程式,从代码中分离出有用的层,帮助设计师和开发者协同工作以及提高我们维护和扩展既有程式的能力。

视图(View)

“视图”主要指我们送到Web浏览器的最终结果——比如我们的脚本生成的HTML。当说到视图时,很多人想到的是模版,但是把模板方案叫做视图的正确性是值得怀疑的。

对视图来说,最重要的事情可能是它应该是“自我意识(self aware)”的,视图被渲染(render)时,视图的元素能意识到自己在更大框架中的角色。

以XML为例,可以说XML在被解析时,DOM API有着这样的认知——一个DOM树里的节点知道它在哪里和它包含了什么。 (当一个XML文档中的节点用SAX解析时只有当解析到该节点时它才有意义。)

绝大多数模板方案使用简单的过程语言和这样的模板标签:

<p>{some_text}</p>
<p>{some_more_text}</p> 它们在文档中没有意义,它们代表的意义只是PHP将用其他的东西来替换它。 如果你同意这种对视图的松散描述,你也就会同意绝大多数模板方案并没有有效的分离视图和模型。模板标签将被替换成什么存放在模型中。 在你实现视图时问自己几个问题:“全体视图的替换容易吗?”“实现一个新视图要多久?” “能很容易的替换视图的描述语言吗?(比如在同一个视图中用SOAP文档替换HTML文档)” 模型(Model) 模型代表了程序逻辑。(在企业级程序中经常称为业务层(business layer)) 总的来说,模型的任务是把原有数据转换成包含某些意义的数据,这些数据将被视图所显示。通常,模型将封装数据查询,可能通过一些抽象数据类(数据访问层)来实现查询。 举例说,你希望计算英国年度降雨量(只是为了给你自己找个好点的度假地),模型将接收十年中每天的降雨量,计算出平均值,再传递给视图。 控制器(controller) 简单的说控制器是Web应用中进入的HTTP请求最先调用的一部分。它检查收到的请求,比如一些GET变量,做出合适的反馈。在写出你的第一个控制器之前,你很难开始编写其他的PHP代码。 最常见的用法是index.php中像switch语句的结构: <?php
  switch ($_GET['viewpage']) {
    case "news":
   $page=new NewsRenderer;
     break;
case "links":
   $page=new LinksRenderer;
     break;
   default:
   $page=new HomePageRenderer;
     break;
     }
    $page->display();
?>
这段代码混用了面向过程和对象的代码,但是对于小的站点来说,这通常是最好的选择。虽然上边的代码还可以优化。 控制器实际上是用来触发模型的数据和视图元素之间的绑定的控件。
q数据库: # Database : `test` # -------------------------------------------------------- #
# Table structure for table `products` #
CREATE TABLE products (
PRODUCTID int(11) NOT NULL auto_increment,
PRODUCTNAME varchar(255) NOT NULL default '',
UNITPRICE varchar(255) NOT NULL default '',
UNITSINSTOCK varchar(255) NOT NULL default '',
DISCONTINUED varchar(255) NOT NULL default '',
PRIMARY KEY (PRODUCTID) ) TYPE=MyISAM;
 # # Dumping data for table `products` #
INSERT INTO products VALUES (1, 'Chai', '18', '39', '0');
INSERT INTO products VALUES (2, 'Chang', '19', '17', '0');
INSERT INTO products VALUES (3, 'Aniseed Syrup', '10', '13', '0');
INSERT INTO products VALUES (4, 'Chef Antons Cajun Seasoning', '22', '53', '0');
INSERT INTO products VALUES (5, 'Chef Anton Gumbo Mix', '21.35', '0', '1'); 例子 这里是一个使用MVC模式的简单例子。
首先我们需要一个数据库访问类,它是一个普通类。
lib/DataAccess.php
<?php
/**
*数据库连接和查询
*$db 数据库连接标识符
*$query 获取数据资源标识符
*/
class DataAccess {
public $db;
public $query;
// 构造函数
function __construct($host, $user, $password, $dbname){
$this->db = mysql_connect($host, $user, $password);
mysql_select_db($dbname, $this->db);
mysql_query("set names utf8");
}
// 获取数据资源标识符
function fetch($sql){
$this->query=mysql_query($sql, $this->db);
}
// 获取数据集
function getRow(){
if($row = mysql_fetch_array($this->query, MYSQL_ASSOC))
return $row;
else
return false;
}
}
?> 在它上边放上模型。
lib/ProductModel.php
<?php
/** * 数据模型(model)
* $dao DataAccess 的一个对象
*/
class ProductModel {
public $dao;
// 构造函数
function __construct(&$dao){
$this->dao = & $dao;
}
// 查询多条数据,并把资源标识符保存在 DataAccess 数据对象的 query 中
function listProducts($start=0, $rows=50){
// 调用 DataAccess 对象的 fetch() 方法,获取并保存资源标识符
$this->dao->fetch("select * from products limit " . $start.", ".$rows);
}
// 查询单条数据,并把资源标识符保存在 DataAccess 数据对象的 query 中
function listproduct($id){
// 调用 DataAccess 对象的 fetch() 方法,获取并保存资源标识符
$this->dao->fetch("select * from products where productid='" . $id."'" );
}
// 从 DataAccess 对象 的资源标识符中获取数据集
function getProduct(){
// 调用 DataAccess 对象的 getRow() 方法,获取数据集
if($product = $this->dao->getRow())
return $product;
else
return false;
}
}
?> 接下来是视图
lib/ProductView.php <?php
/**
* 数据视图(view)
* $model ProductModel 一个对象
* $output 输出的字符串
*/
class ProductView {
public $model;
public $output;
// 构造函数
function __construct(&$model){
$this->model = &$model;
}
// 头部内容
function header(){
$this->output="<a href=\"".$_SERVER['PHP_SELF']."\">Start Over</a>";
}
// 底部内容
function footer(){
$this->output.="";
}
// 获取单条详细的数据信息
function productItem($id=1){
// 调用 ProductModel 对象的 listProduct()方法来调用DataAccess 对象的 fetch() 方法,获取并保存资源标识符
$this->model->listProduct($id);
// 调用ProductModel 对象中的 getProduct() 方法来调用DataAccess 对象的 getRow() 方法,从标识符中读取数据集
while($product=$this->model->getProduct()){
$this->output.=$product['PRODUCTID'].' ==> ' . $product['PRODUCTNAME'].
$product['UNITPRICE'].
$product['UNITSINSTOCK'];
if($this->product['DISCONTINUED'] == 1){
$this->output.="This product has been discontinued.";
}
}
}
// 获取多条数据集合
function productTable($rownum=0){
$rowsperpage = 20;
// 调用 ProductModel 对象的 listProduct()方法来调用DataAccess 对象的 fetch() 方法,获取并保存资源标识符
$this->model->listProducts($rownum, $rowsperpage); // 调用ProductModel 对象中的 getProduct() 方法来调用DataAccess 对象的 getRow() 方法,从标识符中读取数据集
while($product = $this->model->getProduct()){
$this->output.="<a href=\"".$_SERVER['PHP_SELF']."?view=product&id=".$product['PRODUCTID']."\">".
$product['PRODUCTID'] . ' ==> ' . $product['PRODUCTNAME']."</a>".
$product['UNITPRICE'];
} if($rownum > 0){
$this->output.="<a href=\"".$_SERVER['PHP_SELF']."?view=table&rownum=".($rownum-$rowsperpage).
"\"><< Prev </a>";
}
if($product['PRODUCTID'] < ($rownum+$rowsperpage)){
$this->output.="<a href=\"".$_SERVER['PHP_SELF']."?view=table&rownum=".($rownum+$rowsperpage).
"\">Next >></a>";
} }
// 显示字符串
function display(){
return $this->output;
}
}?>
最后是控制器,我们将把视图实现为一个子类。
lib/ProductController.php <?php
/**
* 控制器(controller)
* 通过继承 ProductView 类
* $model 是 ProductModel 的一个对象实例
* $getvars 是一个 $_GET 的参数数组
* index.php?view=product&id=5
* index.php?view=table&rownum=20
*/
class ProductController extends ProductView {
function __construct(&$model, $getvars = null){
parent::__construct(&$model);
switch($getvars['view']){
case "product":
// 调用 ProductView 对象中的 productItem()方法来显示数据
$this->productItem($getvars['id']);
break;
default:
// 调用 ProductView 对象中的 productItem()方法来显示数据
if(empty($getvars['rownum'])){
$this->ProductTable();
}else{
$this->productTable($getvars['rownum']);
}
break;
}
}
}
?>
最后是调用的首页 index.php <?php
require_once('lib/DataAccess.php');
require_once('lib/ProductModel.php');
require_once('lib/ProductView.php');
require_once('lib/ProductController.php');
$dao =& new DataAccess('localhost', 'root', '123456', 'test');
$productModel = &new ProductModel($dao);
$productController = & new ProductController($productModel, $_GET);
echo $productController->display();
?>

  

php MVC 及例子解释的更多相关文章

  1. 【Spring】简单的Spring MVC入门例子

    前言 测试特性需要搭建一个简单的Spring MVC的例子,遂记录之,只是例子,只为入门者之示例. 版本说明 声明POM文件,指定需引入的JAR. <properties> <spr ...

  2. java web中Jdbc访问数据库步骤通俗解释(吃饭),与MVC的通俗解释(做饭)

    一.Jdbc访问数据库步骤通俗解释(吃饭) 1)加载驱动 Class.forName(“com.microsoft.jdbc.sqlserver.SQLServer”); 2) 与数据库建立连接 Co ...

  3. 用通俗的例子解释OAuth和OpenID的区别【原】

    什么是OAuth(Wiki) 什么是OpenID(Wiki) 详细的定义可以看wiki,下面举个例子说说我的理解 现在很多网站都可以用第三方的账号登陆,比如,现在我要登录淘宝买东西,而如果我没有淘宝的 ...

  4. spring mvc的例子

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  5. 首个spring mvc 测试例子搭建遇到问题记录

    开发环境:jdk1.7 + tomcat7 + Eclipse Juno 首先下载spring 相关jar包 我用的是 spring-framework-3.2.1.RELEASE 下载地址:http ...

  6. 小例子解释wait与notify的区别

    系统慢可能有很多种原因,硬件资源不足,语句不优化,结构设计不合理,缺少必要的运维方式.所有的这些问题都可以在阻塞与等待中看出端倪,发现并解决问题. 首先是下载开发工具,磨刀不误砍材工.点此下载 这是一 ...

  7. 一个很小的C&plus;&plus;写的MVC的例子

    #include<iostream> #include<vector> //get namespace related stuff using std::cin; using ...

  8. MVC简单的解释

    MVC (Model-View-Controller,模型视图控制器)是一种软件的设计模式,它最早是由 20 世纪 70 年代的 Smalltalk 语言提出的,即把一个复杂的软件工程分解为三个层 ...

  9. ASP&period;NET MVC简单流程解释(传值方式)

    在上篇笔记里我们创建了一个简单的MVC程序 在view中,@Model指的就是MyFirstMvc.Models.IndexModel,我们的提交页面是/Test/Index,当我们输入完数字并按下提 ...

随机推荐

  1. 完美解决scrollView 截屏图片模糊

    UIGraphicsBeginImageContext   首先说明一下UIGraphicsBeginImageContextWithOptions 和UIGraphicsBeginImageCont ...

  2. 无刷新 checkbox列表的删除

    前台 JS : function ModelDelete() { var checkvalues = null; var checValue = $("#dom1").find(& ...

  3. Linux下编译OpenSSL

    编译环境 操作系统: Red Hat Enterprise Linux Server release 5.4 64-bit 编译工具: gcc (GCC) 4.1.2 20080704 (Red Ha ...

  4. AT&amp&semi;T汇编中系统调用和C函数调用的使用

    我的博客:www.while0.com 区别: 系统调用的参数存储在寄存器中,函数调用的则存储在堆栈中. 系统调用使用中断方式,函数调用使用call指令 相同之处: 都有返回值和输入值 返回值都存储在 ...

  5. 我的Python之旅第四天

    一 名称空间.作用域.取值顺序 1 名称空间 当程序运行时,代码从上至下依次执行,它会将变量与值得关系存储在一个空间中,这个空间就叫做名称空间,也叫命名空间.全局名称空间. 当程序遇到函数时,他会将函 ...

  6. BBS论坛(十七)

    17.首页导航条实现和代码抽离 (1)temlates/common/_head.html <meta name="csrf-token" content="{{ ...

  7. 解决端口冲突问题(查询端口占用进程并kill)

    1. 查看端口占用 在windows命令行窗口下执行: netstat -aon|findstr "8080" TCP 127.0.0.1:80 0.0.0.0:0 LISTENI ...

  8. 前后台交互经常使用的技术汇总(后台:Java技术,前台:Js或者Jquery)

    1:由于针对特定的前后台交互用到的知识总结,所以不大量贴代码,主要给出思路,方便自己以后脑补和技术总结,当然也希望可以帮助到别人. 后台Json和其他格式转化,之前总结过Json和对象,集合,字符串的 ...

  9. 程序中打印当前进程的调用堆栈&lpar;backtrace&rpar;

    为了方便调式程序,产品中需要在程序崩溃或遇到问题时打印出当前的调用堆栈.由于是基于Linux的ARM嵌入式系统,没有足够的空间来存放coredump文件. 实现方法,首先用__builtin_fram ...

  10. &period;NetCore实践篇:成功解决分布式监控ZipKin聚合依赖问题(三)

    前言 读本篇文章之前,可以先读前两篇文章.为了照顾没看过的朋友,我也会稍作复习. 思考大纲: .Net架构篇:思考如何设计一款实用的分布式监控系统? 实践篇一:.NetCore实践篇:分布式监控客户端 ...