入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

MVC框架浅析(基于PHP)

创建时间:2016-06-09 投稿人: 浏览次数:4745

MVC框架浅析(基于PHP)

      MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

一.MVC概念

      MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式,它们各自处理自己的任务:
      MVC 模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制。


Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。
  通常模型对象负责在数据库中存取数据。
View(视图)是应用程序中处理数据显示的部分。
  通常视图是依据模型数据创建的。
Controller(控制器)是应用程序中处理用户交互的部分。
  通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。


      MVC 分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。
      MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。

      有很多程序员往往认为MVC是一种设计模式。实际上MVC是一种框架模式。框架通常是代码重用,而设计模式是设计重用,架构则介于两者之间,部分代码重用,部分设计重用,有时分析也可重用。

      简而言之:框架是大智慧,用来对软件设计进行分工;设计模式是小技巧,对具体问题提出解决方案,以提高代码复用率,降低耦合度。

二.MVC理解

面向对象的思维

获取和描述系统的用户需求;

识别角色和用例,画UseCase;

根据功能从用例图中找三种类型类:实体类、边界类和控制类;将所有找到的三种类集中综合在一起得到三大模型:实体模型、视图模型、逻辑模型。实际上对应着MVC。进而进行WEB建模。

三.MVC实践

      MVC是一种框架模式,只有在实例中才能更好的理解MVC。本文基于ThinkPHP3.2.3的MVC框架,实现一个简单的留言板系统。

1.    ThinkPHP3.2.3

      ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。
      ThinkPHP可以支持windows/Unix/Liunx等服务器环境,支持MySql、PgSQL、Sqlite以及PDO等多种数据库。作为一个整体开发解决方案,它包含了底层架构、兼容处理、基类库、数据库访问层、模板引擎、缓存机制、插件机制、角色认证、表单处理等常用的组件,并且对于跨版本、跨平台和跨数据库移植都比较方便。
      ThinkPHP3.2.3是最新版本. 获取地址:http://www.thinkphp.cn/,(初学建议下载完版)。
      ThinkPHP需要集成环境,这里用Wampserver。Wamp就是Windows Apache Mysql PHP集成安装环境,即在window下的apache、php和mysql的服务器软件。PHP扩展、Apache模块,开启/关闭鼠标点点就搞定,再也不用亲自去修改配置文件了,WAMP它会去做。
      获取地址:http://www.wampserver.com/en/

2.  需求分析和原型设计
2.1 系统需求

      用户进行注册,然后登陆系统,进行留言。

2.2 原型设计

      Axure RP 能帮助网站需求设计者,快捷而简便的创建 基于目录组织的原型文档、功能说明、交互界面以及带注释的wireframe网页,并可自动生成用于演示的网页文件和word文档,以提供演示与开发。
      获取地址:http://www.axure.com/

2.2.1 登陆页面:

image

2.2.2 注册页面:

image

2.2.3 系统页面:

image

2.3 功能设计

注册模块:注册用户
登录模块:登录    退出                
留言模块:提交留言信息    显示留言信息

2.4 数据库设计    
2.4.1 分析:

用户表:用户名、密码、性别            
留言表:留言题目、留言内容、附件名、留言时间
用户表与留言表之间是一对多的关系,需要在留言表中设置外键。      

 2.4.2 设计:

用户表(tp_user)

字段

类型

notnull

默认值

备注

id

Int

notnull

 

主键 自增

username

varchar(30)

 

‘’

用户名

password

char(32)

 

‘’

密码

sex

tyint

notnull

1

性别:1代表男 0 代表0

留言表(tp_message)

字段

类型

notnull

默认值

备注

id

Int

notnull

 

主键 自增

title

varchar(60)

 

‘’

题目

content

test

 

‘’

内容

filename

varchar(30)

notnull

1

附件名

time

int

   

时间:时间戳格式

uid

int

   

外键:用户表中的id

3. ThinkPHP设计思想与目录文件

      在Wampserver安装地址下的www文件夹下新建项目think_message。将ThinkPHP_3.2.3_full.zip解压放到think_message中。

      在浏览器中,打开项目think_message,ThinkPHP会自动在Application文件夹下创建Home文件夹,它是前台模块;同样我们可以在Application下创建后台模块,本留言系统暂时不建立后台模块。到此ThinkPHP环境基本搭建完毕。

3.1 解压缩可以看到初始的目录结构如下:

image

3.2 ThinkPHP内核 框架设计

image

3.3 模块设计

image

每个模块是相对独立的,其目录结构如下:

image

以后我们主要在Controller、Model和View三个文件下实施项目,即MVC。

4.  实施项目

      本项目用sublime编辑器,进行代码编辑。

4.1 打开phpmyadmin,建立数据库messge

新建tp_user表和tp_message表,按照数据库设计对应键入。注意:整理项Collation选择 utf8- general-ci。

4.2 连接数据库

Application->Common->Conf下的config.php,键入一下代码:

复制代码
//数据库配置信息
    "DB_TYPE" => "mysql", // 数据库类型
    "DB_HOST" => "localhost", // 服务器地址
    "DB_NAME" => "message", // 数据库名
    "DB_USER" => "root", // 用户名
    "DB_PWD" => "", // 密码
    "DB_PORT" => 3306, // 端口
    "DB_PREFIX" => "tp_", // 数据库表前缀
    "DB_CHARSET"=> "utf8", // 字符集
复制代码
4.3 编码

      在根目录下Public下建立Css、Js、Images和Uploads四个文件夹,分别用于存储系统的css代码、js代码、系统所用的图片资源和用户上传的文件资源。

      根据功能设计,我们首先在Application->Home->Controller,建立三个控制器:RegisterController.class.php、LoginController.class.php、MessageController.class.php;以及建立IndexController.class.php控制器,系统默认进入的控制器。以后有需要我们再添加。控制器里面是函数,处理不同逻辑需求。

      根据所建控制器及要显示的页面,在Application->Home->View下,分别创建Index(系统页面)、Register(注册页面)和Login(登陆页面)文件夹,用于原型设计的三个页面显示。

4.3.1 注册

功能:实现用户注册

V

注册需要显示注册页面,我们在Home->View->Register文件夹下创建reg.html用于显示注册页面。代码如下:

复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>注册</title>
        <load href="__PUBLIC__/Css/Home/reg.css" />
        <load href="__PUBLIC__/Js/jquery.js"/>
        <load href="__PUBLIC__/Css/basic.css" />
        
        <script>
            $(function(){
                var error=new Array();
                $("input[name="username"]").blur(function(){
                    var username=$(this).val();
                    $.get("__URL__/checkName",{"username":username},function(data){
                        if(data=="不允许"){
                            error["username"]=1;
                            $("input[name="username"]").after("<p id="umessage" style="color:red">该用户名已经注册</p>");
                        }else{
                            error["username"]=0;
                            $("#umessage").remove();
                        }
                    });
                });

                //提交表单
                $("img.register").click(function(){
                    if(error["username"]==1){
                        return false;
                    }else{
                        $("form[name="myForm"]").submit();
                    }
                });
            });
        </script>
    </head>
    <body>
        <form action="__URL__/doReg" method="post" name="myForm">
            用 户 名:<input type="text" name="username"/><br/>
            密  码:<input type="password" name="password"/><br/>
            确认密码:<input type="password" name="repassword"/><br/>
            性  别:<input type="radio" name="sex" value="1" class="radio"/>男
                  <input type="radio" name="sex" value="0" class="radio"/>女<br/>
            验 证 码:<input type="text" name="code"/>
                       <img src="__MODULE__/Public/code" onclick="this.src=this.src+"?"+Math.random()"/>
                      <br/>
            <img src="__PUBLIC__/Images/register.gif" class="register"/>
            <img src="__PUBLIC__/Images/reset.gif" class="reset"/>
        </form>
    </body>
</html>
复制代码

C

RegisterController.class.php控制器代码如下:

复制代码
<?php
namespace HomeController;
use ThinkController;
class RegisterController extends Controller {
    //显示注册页面
    public function reg(){
        $this->display();
    }

    //检查用户是否注册过
    public function checkName(){
        $username=$_GET["username"];
        $user=M("User");
        $where["username"]=$username;
        $count=$user->where($where)->count();
        if($count){
            echo "不允许";
        }else{
            echo "允许";
        }
    }
    //注册
    public function doReg(){
    
        $user=D("User");
        if(!$user->create()){
            $this->error($user->getError());
        }
    
        $lastId=$user->add();
        if($lastId){
            $this->redirect("Index/index");
        }else{
            $this->error("用户注册失败");
        }

    }
}
?>
复制代码

建立了PublicController.class.php控制器,设置验证码的属性。代码如下:

复制代码
<?php
namespace HomeController;
use ThinkController;
class PublicController extends Controller {
    public function code(){
        $Verify = new ThinkVerify();
        $Verify->fontSize = 16;  
         $Verify->length   = 4;
        $Verify->imageW = 130;  
         $Verify->imageH = 30;
        $Verify->entry();
}
}
?>
复制代码

M

前台的验证只是提供用户体验,安全还是要后台进行验证。TinkPHP实现自动验证,在Home->View->Model下,新建UserModel.class.php模型,进行自动验证。代码如下:

复制代码
<?php
namespace HomeModel;
use ThinkModel;

class UserModel extends Model{
    protected $_validate=array(
        array("code","require","验证码必须填写!"),
        array("code","checkCode","验证码错误!",0,"callback",1),
        array("username","require","用户必须填写!"),
        array("username","","用户已经存在",0,"unique",1),
        array("username","/^w{6,}$/","用户名必须6个字母以上",0,"regex",1),
        array("repassword","password","确认密码不正确",0,"confirm"), 
    );

    protected function checkCode($code){
        function check_verify($code, $id = ""){
            $verify = new ThinkVerify();
            return $verify->check($code, $id);
        }

        if(!check_verify($code,$id = "")){
            return false;
        }else{
            return true;
        }
    }
}
?>
复制代码
4.3.2 登陆

功能:实现用户登陆

V

登陆页面需要显示,我们在Home->View->Login文件夹下创建login.html用于显示注册页面。代码如下:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <load href="__PUBLIC__/Css/basic.css" />
    <load href="__PUBLIC__/Css/Home/login.css" />
    <load href="__PUBLIC__/Js/jquery.js"/>
    <script>
        $(function(){
            $("img[title="login"]").click(function(){
                $("form[name="myForm"]").submit();
            });

            $("img[class="register"]").click(function(){
                    window.location="__APP__/Home/Register/reg";
            });
        });
    </script>
</head>
<body>
    <form action="__URL__/doLogin" method="post" name="myForm">
        用户名:<input type="text" name="username"/><br/>
        密 码:<input type="password" name="password"/><br/>
        验证码:<input type="text" name="code"/>
        <img src="__MODULE__/Public/code" onclick="this.src=this.src+"?"+Math.random()"/><br/>
        <img src="__PUBLIC__/Images/login.gif" title="login" class="submit"/>
        <img src="__PUBLIC__/Images/register.gif" class="register"/>
    </form>        
</body>
</html>
复制代码

C

LoginController.class.php控制器代码如下:

复制代码
<?php
namespace HomeController;
use ThinkController;

class LoginController extends Controller {
    //显示登陆页面
    public function index(){
        $this->display();
    }

    public function doLogin(){
        //接受值
        //判断用户在数据库中是否存在
        //存在 允许登录
        //不存在 显示错误信息
        $username=$_POST["username"];
        $password=$_POST["password"];
        $code=$_POST["code"];
        
        function check_verify($code, $id = ""){
            $verify = new ThinkVerify();
            return $verify->check($code, $id);
        }

        if(!check_verify($code,$id = "")){
            $this->error("验证码输入错误!");
        }

        $user=M("User");
        $where["username"]=$username;
        $where["password"]=$password;
        $arr=$user->field("id")->where($where)->find();
        if($arr){
            $_SESSION["username"]=$username;
            $_SESSION["id"]=$arr["id"];
            $this->success("用户登录成功",U("Index/index"));
        }else{
            $this->error("该用户不存在");
        }
    }
}
?>
复制代码
4.3.3 系统页面

功能:实现用户用户留言

V

系统页面使用frameset将整个页面分为3部分top,left,right,我们在Home->View->Index文件夹下创建index.html、top.html、left.html,right.html。代码如下:

index.html。代码如下:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>

<frameset rows="20%,*">
    <frame src="__URL__/top" name="top"/>
    <frameset cols="50%,50%">
        <frame src="__URL__/left" name="left"/>
        <frame src="__URL__/right" name="right"/>
    </frameset>
</frameset>
</html>
复制代码

top.html,用于显示欢迎。代码如下:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>top</title>
</head>
<body>
    <p>欢迎你 <strong>{$Think.session.username}</strong> !<a href="__APP__/Home/Login/doLogout" target="_top">退出</a></p>
    <h1 align="center">ThinkPHP留言板系统</h1>
</body>
</html>
复制代码

left.html,用于显示所有的留言内容。代码如下:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Left</title>
</head>
<body>
    <foreach name="list" item="vo">
        留言题目:{$vo.title}<br/>
        <p>留言内容:</p>{$vo.content}<br/>
        附件名:{$vo.filename}<br/>
        {$vo.username}  {$vo.time|date="Y/m/d H:i:s",###}<br/>
        <hr/>
    </foreach>
    {$show}
</body>
</html>
复制代码

right.html,用于提交留言。代码如下:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Right</title>
</head>
<body>
    <form action="__MODULE__/Message/doMess" method="post" enctype="multipart/form-data">
        留言题目:<input type="text" name="title"/><br/>
        留言内容:<textarea name="content"></textarea><br/>
        附  件:<input type="file" name="filename"/><br/>
        <input type="submit" value="提交留言"/>
    </form>
</body>
</html>
复制代码

C

IndexController.class.php控制器,用于页面的整体显示。代码如下:

复制代码
<?php
namespace HomeController;
use ThinkController;
class IndexController extends CommonController {
    public function index(){
        $this->display();
    }

    public function top(){
        $this->display();
    }

    public function left(){
        $message=D("Message");
        $count=$message->count();//获取数据的总数
        $Page = new ThinkPage($count,3);// 实例化分页类 传入总记录数和每页显示的记录数(3)
        $show = $Page->show();// 分页显示输出
        $arr=$message->relation(true)->order("time desc")->limit($Page->firstRow.",".$Page->listRows)->select();
        $this->assign("list",$arr);
        $this->assign("show",$show);
        $this->display();
    }

    public function right(){
        $this->display();
    }
}
?>
复制代码

MessageController.class.php控制器,用于留言的逻辑控制。代码如下:

复制代码
<?php
namespace HomeController;
use ThinkController;

class MessageController extends Controller {
    public function doMess(){
            
        $upload = new ThinkUpload();// 实例化上传类
        $upload->rootPath = "./Public/Uploads/";//设置附件上传目录
        $info = $upload->upload();
        if(!$info) {// 上传错误提示错误信息
            $this->error($upload->getError());
        }else{// 上传成功 获取上传文件信息
            foreach($info as $file){
            // $savename=$file["savepath"].$file["savename"];
                $savename=$file["savename"];
            }
        }

        $message=D("Message");
        $message->create();
        $message->filename=$savename;
        // $message->time=time();
        // $message->uid=$_SESSION["id"];
        $lastId=$message->add();
        if($lastId){
            $this->success("留言成功");
        }else{
            $this->error("留言失败");
        }
    }
}
?>
复制代码

M

TinkPHP实现自动完成,并实现tp_user表和tp_messgae表的关联取字段值,在Home->View->Model下,新建MessageModel.class.php模型,进行自动验证。代码如下:

复制代码
<?php
namespace HomeModel;
use ThinkModelRelationModel;

class MessageModel extends RelationModel{
    protected $_auto=array(
        array("time","time",1,"function"),
        array("uid","getId",1,"callback"),
    );

    protected $_link=array(
        "User"=> array(  
             "mapping_type" => self::BELONGS_TO,
              "class_name"=>"User",
              "foreign_key"=>"uid",
            "mapping_name"=>"user",
            "mapping_fields"=>"username",
            "as_fields"=>"username",
        ),    
    );
        
    protected function getId(){
        return $_SESSION["id"];
    }
}
?>
复制代码

 

为了网站安全

必须进行登录才能进入任何一个页面,添加CommonController.class.php控制器。代码如下:

复制代码
<?php
namespace HomeController;
use ThinkController;
class CommonController extends Controller {
    Public function _initialize(){
           // 初始化的时候检查用户权限
        if(!isset($_SESSION["username"]) || $_SESSION["username"]==""){
            $this->redirect("Login/login");
        }
    }
}
?>
复制代码

最终的文件目录如下:

image

至此基于PHP的MVC思想建立的留言系统已完成。

四.结束

      MVC框架模式对项目的效率和可重用是至关重要的。当然在开发时我们应该灵活的应用MVC。也有新的框架模式不断涌现,相互参考才是最重要的。

      留言系统源代码:https://github.com/jingwhale/mvc-php-messagesystem。

from: http://www.cnblogs.com/jingwhale/p/4303684.html

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。