1. 程式人生 > >用PHP開始你的MVC(三)實現你的Model層

用PHP開始你的MVC(三)實現你的Model層

三、實現你的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的值,因此不能通過資料的完整性校驗,抱錯.

相關推薦

PHP開始MVC()實現Model

三、實現你的Mode層Model層,就是MVC模式中的資料處理層,用來進行資料和商業邏輯的裝封,進行他的設計的時候設計到三個個概念:------Model類。是實體類。用來儲存資料庫表格的中一條記錄的所有欄位的資料。並且可以驗證這條記錄資料的完整性。------ModelMa

PHP開始MVC (四)實現View

MVC模式的view層的主要任務是進行頁面的和結果的顯示工作,在php的實現過程中,主要是體現為一個模板(使用模板,可以達到php程式碼和html程式碼分離的目的,這樣程式碼和頁面的維護就方便多了,便於管理和頁面的更換,可以真正的劃分程式設計師、美工的分工)的解析過程:首先,

PHP開始MVC (一)整合的站點入口

這是一篇介紹如何用php來實現MVC模式開發的檔案。關於MVC模式的技術文章網上隨處可以,所以這篇檔案將不再講述這種模式的優缺點(實際上是我說不清楚),子講他的php技術實現。並且在以後的系列文章中也是以講技術為主。一、實現統一的網站入口(在MVC中呼叫Controler層的方法,也就是控制層)大家也許經常在

跟著辛星PHP的反射機制來實現插件

red 實現 track 這一 列表 each 方法 fun 繼承 我的博文的前一篇解說了PHP的反射機制是怎麽回事,假設讀者還不清楚反射機制,能夠搜索下或者看我的博文,都是不錯的選擇。我們開始解說一下怎麽用PHP來實現插件機制。所謂插件機制。就是我們定義

跟著辛星PHP的反射機制來實現外掛

     我的博文的前一篇講解了PHP的反射機制是怎麼回事,如果讀者還不清楚反射機制,可以搜尋下或者看我的博文,都是不錯的選擇,我們開始講解一下怎麼用PHP來實現外掛機制。所謂外掛機制,就是我們定義一個介面,即我們定義一個interface,然後第三方外掛就去實現這個int

PHP下基於MVC結構實現支付寶交易介面

最近因為工作需要學習使用了支付寶的“即時到賬交易介面”,在學習應用的過程中走了很多的彎路,也感覺到官方說明文件中有些許不足 ,這裡一併總結下來。 <h2>名詞解釋:</h2> 商戶:通過支付寶來銷售商品的商家,即支付寶介面實現者。 客戶:通過支付寶購

從0到1java再造tcpip協議棧:實現ARP協議

經過前兩節的準備,我們完成了資料鏈路層,已經具備了資料包接收和傳送的基礎設施,本機我們在此基礎上實現上層協議,我們首先從實現ARP協議開始。先簡單認識一下ARP協議,ARP是一種定址協議,它要找尋目標的實體地址,連線在網際網路上的裝置有兩種地址,一種叫IP,也就是我們常見的192.168

ES6學習筆記():教js面向物件思維來實現 tab欄增刪改查功能

前兩篇文章主要介紹了類和物件、類的繼承,如果想了解更多理論請查閱《ES6學習筆記(一):輕鬆搞懂面向物件程式設計、類和物件》、《ES6學習筆記(二):教你玩轉類的繼承和類的物件》,今天主要來分享關於如何用js面向物件的思維來實現tab欄的一些相關的功能。 要實現的功能分析 點選tab欄可以切換效果 點選

PHP到底有多牛?所知道的網站都在

  PHP到底有多牛?你所知道的網站都在用它   提起PHP,很多人的第一印象就是網站開發,確實,在網站開發方面,PHP難逢對手,當之無愧是“世界上最好的語言”。   有資料顯示,目前全球5000萬網際網路網站中,有60%以上使用著php技術,在國內,80%網際網路網站使用php開發。   不僅如此,人

富貴教PHP爬取掘金文章

前言 最近忙完了專案比較空就打算深入學習一些關於爬蟲的知識,以前讀書的時候就喜歡用爬蟲去爬一些學習網站(波多野**老師)。寫這篇部落格是想對之前學習的一些爬蟲知識做一個梳理和交流。希望有大佬指出不足,幫我成長。 新手村任務 下面這些是我2018年這半年業餘時間研究的一些小東西,比較適合剛

PHP常見面試題 PHP框架基礎-MVC框架基本工作原理】談談MVC的認識,介紹幾種目前比較流行的MVC框架。

一、考點 1、MVC工作原理 1)工作原理 Model - 資料模型層:通常情況下對資料進行加工,進行一些其他的處理,與資料相關的一些操作都在 Model層 操作。 View - 檢視層:跟使用者進行互動的一些介面上的東西。 Controller - 控制層

一步一步教PHP+MySql搭建網站 No.0 準備工作

新開一個系列教程吧,這次是講如何用PHP+MySQL搭建網站。 之前一直有想過搭建自己的個人網站,然後上週通過阿里雲申請的域名和空間都通過稽核了,於是就開始研究如何用PHP+MYSQL搭建網站,研究了差不多兩週,總算搞定了一個小型的blog類的網站。當然,整個過程是通過學習

怎麼php將微信與第三方平臺打通(建議使用測試號 【功能多】)

新建一個php檔案 寫上如下程式碼<?php echo $_GET["echostr"]; ?> 然後上傳到阿里雲主機 或其他都可以  最後就可以配置成功了下面這段程式碼 是安全驗證  相當於漏洞補丁驗證訊息的確來自微信伺服器private

一步一步教PHP+MySql搭建網站 No.1 主頁&資料庫連線

這一章節我們來看使用者輸入網頁後的主介面。 一般來說,預設主頁都是index點xxx,比如 index.php, index.html , index.jsp等等。我們來看一下我們的index.php吧 index.php 提醒: 在<?php?>的兩端,不要

手把手教如何運用強大的谷歌自定義搜尋功能來實現的自定義搜尋站之谷歌自定義搜尋實現網盤搜尋引擎第一篇

今天給大家講解一下如何運用谷歌自定義搜尋功能來實現你自己的個性化搜尋網站,我們以實現網盤搜尋引擎為例進行展開說明,學會了這個,你可以做搜尋任何東西的網站,不僅僅是網盤資源搜尋引擎啦!對了,要用這個功能

Python 實現的量化交易策略

Python 的學習者中,有相當一部分是衝著爬蟲去的。因為爬蟲可以幫你解決很多工作和生活中的問題,節約你的生命。不過 Python 還有一個神祕而有趣的應用領域,那就是量化交易。 量化交易,就是以數學模型替代人的主觀判斷來制定交易策略。通常會藉助計算機程式來進行策略的計算和驗證,最終也常直接用程式根

PHP如何實現檔案寫入前追加,如依次寫入"我 愛 ",而實現的效果是"愛我"

<?php   //因為傳統的寫入是前追加或者覆蓋,所以我們需要先讀取拼接再寫入   $file = file_get_contents('hello.txt');//假設檔案裡面已有"愛我"兩

python實現的繪畫夢想

導語: ​ 你是否還在為當時年少時沒有選擇自己的夢想而傷心,是否還在為自己的無法成為繪畫名家而苦惱,這一切都不需要擔心。python都能幫你實現,誒!python怎麼能畫畫呢,一些簡單的圖案沒問題,但是我要是想畫素描那肯定沒有辦法了呀! 需求分析: 通過python程式碼指令碼,實現繪製素描 安裝工具

NN入門,手把手教Numpy手撕NN()

NN入門,手把手教你用Numpy手撕NN(3) 這是一篇包含極少數學的CNN入門文章 上篇文章中簡單介紹了NN的反向傳播,並利用反向傳播實現了一個簡單的NN,在這篇文章中將介紹一下CNN。 CNN CV(計算機視覺)作為AI的一大研究方向,越來越多的人選擇了這個方向,其中使用的深度學習的方法基本以卷積神經網路

在瀑布下火焰烤餅:步法助快速定位網站效能問題(超詳細)

> DevUI是一支兼具設計視角和工程視角的團隊,服務於華為雲[DevCloud](https://www.huaweicloud.com/devcloud/)平臺和華為內部數箇中後臺系統,服務於設計師和前端工程師。 > 官方網站:[devui.design](https://devui.desi