• PHP MVC 中的MODEL层


    Model层,就是MVC模式中的数据处理层,用来进行数据和商业逻辑的装封

    三、实现你的Mode层

    Model层,就是MVC模式中的数据处理层,用来进行数据和商业逻辑的装封,进行他的设计的时候设计到三个个概念:
    ------Model类。是实体类。用来保存数据库表格的中一条记录的所有字段的数据。并且可以验证这条记录数据的完整性。
    ------ModelManager类。 是实体类的管理类。通常每一个实体类(Model)都要有一个对应的管理类(ModelManager)。管理类可以用来管理实体类里面的数据纪录(例如删除/添加/更改.....)。 但是ModelManager类不一定要有对应的Model类。
    ------db类。 用来管理对数据库的联接。 ModelManager类所有的对数据的操作。都是通过这个db类来实现的。 在整个MVC模式中。只有这个db类可以直接对数据库进行操作。同时也只有ModelManager类可以对db类进行调用。

    看上去好象是比较麻烦。但是实际上并不复杂。这种Model层设计方式。和网上购物系统的购物车程序是极其相似的。Model可以看作是购物车里的单个商品的信息类。Manager可以看作是订单。 订单是用来管理采购的商品的。

    下面是一个简单的例子。应该是比较典型的。着重看他的整个设计和流程的实现。仔细研究一下。其实不难。

    注意:下面例子使用的所有的类和方法都是经过简化的。实际情况比这个要复杂的多。但是。作为一个实例已经是足够用了。


    文件夹结构:

    |- Db.php
    |- Model.php
    |- Manager.php
    |- ModelTest1.php
    |- ModelTest2.php
    |- ModelTest3.php
    |- ModelTest4.php
    |- Model /
    |- Model / ClassModel.php
    |- Model / StudentModel.php
    |- Model / ClassManager.php
    |- Model / StudentManager.php
    注意文件夹和文件名的大小写
     


    内容:假设有一个数据库,保存在两张表,一张是class(班级)表格,一张是student(学生)的表格,

    class表格字段:  cls_id----------int--------not null
                        cls_name--------string-----not null
                        cls_address-----string-----null

    student表格字段:stu_id----------int--------not null
         stu_clsid-------int--------not null
            stu_name--------string-----null
     


    ClassModel.php 里面是class表的一个实体类ClassModel
    ClassManager.php 里面是ClassModel的管理类ClassManager
    StudentModel.php 里面是student表的一个实体类StudentModel
    StudentManager.php 里面是StudentModel的管理类StudentManager
    Db.php 里面是一个数据库操作管理类,他和里面用的接口和正常使用情况是一样的, 但是本例只是模拟的实现了这个借口.因此,可以在不用真实数据库的情况下运行.
     


    文件0:(Model.php)Model层实体的基础类

    <?php
    //用来包装信息实体的基础类
    class Model{
        //这个实体类的数据,
        //example: array("id"=>1, "name"=>"this is name");
        var $data;
        //这个实体类的数据约束信息,用来判断加入的$data数据的准确性
        //see: ClassModel
        var $match;
        //与该实体对应的数据库中表的名称
        var $table;
        //初始化
        function Model(&$data){
            $this->data = &$data;
        }
        //设置该实体的某个数据是值
        function set($key, $value){
            $this->data[$key] = $value;
        }
        //获取该实体的某个数据
        function get($key){
            return $this->data[$key];
        }
        //获取该实体的全部数据
        function getData(){
         return $this->data;
        }
        //获取该实体的约束信息
        function getMatch(){
         return $this->match;
        }
        //验证实体数据的准确性和完整性
        function isValid(){
            foreach($this->match as $key=>$value){
                if(!isset($value["null"]) && !isset($this->data[$key])) die("$key 的数值不能为空");
                //.....可以在加其他的判断,例如是否超过如许的最大数值,或长度过长.....
            }
        }
    }
    ?>
     


    文件1:(Manager.php)Model层进行实体管理的基础类

    <?php
    //对实体信息进行管理的基础类
    class Manager{
        //数据库管理类对象
        var $db;
        //初始化
        function Manager(){
         $this->db = new Db();
        }
        //用来向数据库中插入实体信息
        function insert(&$model){
         $model->isvalid();
            $table = $model->table;
            $match = $model->getMatch();
            $data = $model->getData();
            $str1 = $str2 = array();
            foreach($match as $key=>$value){
             if(isset($data[$key])){
                 $str1[] = $key;
                    $str2[] = ($value["type"]=="C")? """.$data[$key].""": $data[$key];
                }
            }
            $sql = "INSERT INTO $table (".implode(",", $str1).") VALUES(".implode(",", $str2).")";
            return $this->db->execute($sql);
        }
    }
    ?>
     


    文件2:(ClassModel.php)班级信息的实体类

    <?php
    //用来包装班级信息的实体类
    class ClassModel extends Model{

        var $data = array();
        //$match中,
        //type用来表示数据的类型(I表示整数, C表示是字符串)
        //name用来表示在数据库表中的字段名
        //null表示该字段的值是否准许为空
        //    (数组中有"null"=>true表示是准许为空,否则不能为空)
        var $match = array("cls_id" => array("name"=>"cls_id", "type"=>"I"),
                           "cls_name" => array("name"=>"cls_name", "type"=>"C"),
                           "cls_address" => array("name"=>"cls_address", "type"=>"C", "null"=>true)
               );

        var $table = "class";
        //初始化
        function ClassModel(&$data){
         parent::Model($data);
        }
        //用来获取这个班级的学生的信息
        function getStudent(){
         require_once "./Model/StudentManager.php";
            $manager = new StudentManager();
            $classId = $this->get("cls_id");
            return $manager->getList($classId);
        }
    }
    ?>
     


    文件3:(StudentModel.php)学生信息的实体类

    <?php
    //用来包装学生信息的实体类
    class StudentModel extends Model{

        var $data = array();
        //$match中,
        //type用来表示数据的类型(I表示整数, C表示是字符串)
        //name用来表示在数据库表中的字段名
        //null表示该字段的值是否准许为空
        //    (数组中有"null"=>true表示是准许为空,否则不能为空)
        var $match = array("stu_id" => array("name"=>"stu_id", "type"=>"I"),
                "stu_clsid" => array("name"=>"stu_clsid", "type"=>"I"),
                           "stu_name" => array("name"=>"stu_name", "type"=>"C", "null"=>true)
                );

        var $table = "student";
        //初始化
    function StudentModel(&$data){
         parent::Model($data);
        }
    }
    ?>
     


    文件4:(ClassManager.php)班级实体的管理类

    <?php
    //班级实体信息的管理类
    class ClassModelManager extends Manager{
        //初始化
    function ClassModelManager(){
            parent::Manager();
        }
        //获取班级列表
        function &getList(){
            $sql = "SELECT * FROM class";
            return $this->db->query($sql);
        }
        //查找并返回一个班级的实体类
        function &findOneModel($id){
         $sql = "SELECT * FORM class WHERE cls_id=$id";
            $data = $this->db->getOne($sql);
            if($data==null) die("该班级不存在!");
            require_once "./Model/ClassModel.php";
            $model = new ClassModel($data);
            return $model;
        }
    }
    ?>
     


    文件5:(StudentManager.php)学生实体的管理类

    <?php
    //学生信息实体的管理类
    class StudentManager extends Manager{
        //初始化
    function StudentManager(){
            parent::Manager();
        }
        //获取某个班级的学生的列表
        function &getList($classId){
            $sql = "SELECT * FROM student WHERE stu_clsid=$classId";
            return $this->db->query($sql);
        }
    }
    ?>
     


    文件6:(Db.php)数据库联接管理类,用于共享并管理数据的访问。由于这个类涉及的内容不是本章要讨论的内容,所以这个类模拟了“真实的数据库管理类的方法”,借口是和正常的类是一样的,但是接口函数里面的内容是不对的,只是模拟的数据。网上有很多这种类的做法,可以自己到晚上找找,(**另外本系列文章的第二章里也有详细的介绍**)。

    <?php
    //数据库操作管理类
    class Db{
       //数据库联接
       var $con;
       //初始化
       function Db(){
           //$this->con=mysql_connect(********************);...........
       }
       //执行数据查询语句
       function &query($sql){
           //$result = mysql_query($sql); ..................
           //return $result;
           if($sql=="SELECT * FROM student WHERE stu_clsid=2")
            return array("0"=>array("stu_id"=>1, "stu_clsid"=>2, "stu_name"=>"student1"),
                          "1"=>array("stu_id"=>2, "stu_clsid"=>2, "stu_name"=>"student2")
                             );
           die("空班级");
       }
       //获取一条数查询结果
       function getOne($sql){
           //$result = mysql_query($sql); .............
           //return $result[0];
           if($sql=="SELECT * FORM class WHERE cls_id=1")
            return null;
           if($sql=="SELECT * FORM class WHERE cls_id=2")
            return array("cls_id"=>2, "cls_name"=>"classname", "cls_address"=>"classaddress");
       }
       //执行数据库更新/添加/删除语句
       function execute($sql){
          //mysql_query($sql);
          echo "<br>正在进行插入操作<br>...<br>插入操作完成<br>";
          return true;
       }
    }
    ?>
     


    测试文件一、(ModelTest1.php)(查询班级标号(cls_id)为2的班级的学生的名单)

    <?php
    error_reporting(E_ALL);
    require_once "Db.php";
    require_once "Model.php";
    require_once "Manager.php";

    $classId = 2;

    require_once "./Model/ClassManager.php";
    $manager = new ClassModelManager();
    $model = $manager->findOneModel($classId);
    $data = &$model->getStudent();
    foreach($data as $value)
    echo "编号:".$value["stu_id"]." ------ 姓名: ".$value["stu_name"]."<br>";
    ?>
     

    返回的结果是:

    编号:1 ------ 姓名: student1
    编号:2 ------ 姓名: student2
     


    测试文件二、(ModelTest2.php)(查询班级标号(cls_id)为1的班级的学生的名单)

    <?php
    error_reporting(E_ALL);
    require_once "Db.php";
    require_once "Model.php";
    require_once "Manager.php";

    $classId = 1;

    require_once "./Model/ClassManager.php";
    $manager = new ClassModelManager();
    $model = $manager->findOneModel($classId);
    $data = &$model->getStudent();
    foreach($data as $value)
    echo "编号:".$value["stu_id"]." ------ 姓名: ".$value["stu_name"]."<br>";
    ?>
     


    返回的结果是:

    该班级不存在!
     


    测试文件三、(ModelTest3.php)(执行数据库的插入工作,向student表添加数据)

    <?php
    error_reporting(E_ALL);
    require_once "Db.php";
    require_once "Model.php";
    require_once "Manager.php";

    $data = array("stu_id"=>3, "stu_clsid"=>2, "stu_name"=>"student3");
    require_once "./Model/StudentModel.php";
    $model = new StudentModel($data);
    require_once "./Model/StudentManager.php";
    $manager = new StudentManager($data);
    $result = $manager->insert($model);
    echo $result? "<h2>插入操作成功</h2>": "<h2>插入操作失败</h2>";
    ?>
     

    返回的结果是:

    正在进行插入操作
    ...
    插入操作完成

    插入操作成功
     


    测试文件四、(ModelTest4.php)(执行数据库的插入工作,向student表添加数据)

    <?php
    error_reporting(E_ALL);
    require_once "Db.php";
    require_once "Model.php";
    require_once "Manager.php";

    $data = array("stu_id"=>3, "stu_name"=>"student3");
    require_once "./Model/StudentModel.php";
    $model = new StudentModel($data);
    require_once "./Model/StudentManager.php";
    $manager = new StudentManager($data);
    $result = $manager->insert($model);
    echo $result? "<h2>插入操作成功</h2>": "<h2>插入操作失败</h2>";
    ?>
     

    返回的结果是:

    stu_clsid 的数值不能为空
     

    结果分析:

    StudentModel中"match"的规定stu_clsid的值是不能为空的,
    而代码中代码中$data = array("stu_id"=>3, "stu_name"=>"student3");
    缺少stu_clsid的值,因此不能通过数据的完整性校验,抱错.

    这个人不懒,写了一点东西
  • 相关阅读:
    高盛、沃尔玛 题做出来还挂了的吐槽
    amazon师兄debrief
    到所有人家距离之和最短的中点 296. Best Meeting Point
    问问题没人回答的情况怎么办终于有解了
    找名人 277. Find the Celebrity
    数组生存游戏 289. Game of Life
    547. Number of Provinces 省份数量
    428. Serialize and Deserialize Nary Tree 序列化、反序列化n叉树
    alias别名简介和使用
    面试官:线程池执行过程中遇到异常会发生什么,怎样处理? Vincent
  • 原文地址:https://www.cnblogs.com/AnonymouL/p/4897054.html
Copyright © 2020-2023  润新知