首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

PHP MVC 實戰(三):落地 Model 層——實體與管理類的協作設計

     編輯:VC 教學

Model 層三大核心角色

在 MVC 中,Model 層不只是「資料庫操作」,更是業務邏輯與資料封裝的核心。設計良好的 Model 層包含三類關鍵角色:

  1. Model 類(實體類):對應資料表單筆記錄,封裝欄位屬性與資料驗證邏輯。
  2. ModelManager 類(管理類):負責實體物件的生命週期管理(CRUD)、業務規則協調。通常一個 Model 對應一個 Manager,但 Manager 也可獨立存在。
  3. Db 類(資料存取層):唯一的資料庫直接操作入口,前文已實作。Manager 透過 Db 間接操作資料,Model 不直接觸碰 Db。

這種分層看似繁瑣,實則職責清晰:Model ≈ 購物車中的單一商品,Manager ≈ 訂單(管理多個商品),Db ≈ 倉庫系統(底層存取)。

專案目錄結構

|- Db.php
|- Model.php
|- Manager.php
|- ModelTest1.php ~ ModelTest4.php
|- Model/
   |- ClassModel.php
   |- StudentModel.php
   |- ClassManager.php
   |- StudentManager.php

資料表設計

表名欄位型別說明
classcls_idint主鍵,非空
cls_namestring班級名稱,非空
cls_addressstring地址,可空
studentstu_idint主鍵,非空
stu_clsidint外鍵關聯 class,非空
stu_namestring學生姓名,可空

核心程式碼實作

1. 基礎 Model 類

<?php
// Model/Model.php
abstract class Model {
    protected $data = [];      // 欄位資料
    protected $errors = [];    // 驗證錯誤

    // 設定屬性(支援鏈式呼叫)
    public function __set($name, $value) {
        $this->data[$name] = $value;
        return $this;
    }

    // 取得屬性
    public function __get($name) {
        return $this->data[$name] ?? null;
    }

    // 轉陣列
    public function toArray() {
        return $this->data;
    }

    // 抽象驗證方法,子類必須實作
    abstract public function validate();
}
?>

2. 實體類:ClassModel

<?php
// Model/ClassModel.php
require_once 'Model.php';

class ClassModel extends Model {
    protected $table = 'class';
    protected $pk = 'cls_id';

    public function validate() {
        $this->errors = [];
        if (empty($this->cls_name)) {
            $this->errors[] = '班級名稱不可為空';
        }
        return empty($this->errors);
    }

    public function getErrors() {
        return $this->errors;
    }
}
?>

3. 基礎 Manager 類

<?php
// Model/Manager.php
require_once '../Db.php';

abstract class Manager {
    protected $db;
    protected $modelClass;

    public function __construct() {
        $this->db = new Db();
    }

    // 新增實體
    public function create(Model $model) {
        if (!$model->validate()) return false;
        $data = $model->toArray();
        unset($data[$model->pk]); // 移除自增主鍵
        $fields = implode(',', array_keys($data));
        $values = "'" . implode("','", array_map([$this->db, 'escape'], array_values($data))) . "'";
        $sql = "INSERT INTO {$model->table} ($fields) VALUES ($values)";
        return $this->db->execute($sql) > 0 ? $this->db->getInsertId() : false;
    }

    // 依主鍵查詢
    public function findById($id) {
        $sql = "SELECT * FROM {$this->modelClass} WHERE {$this->pk} = $id";
        $row = $this->db->fetchRow($this->db->query($sql));
        if (!$row) return null;
        $model = new $this->modelClass();
        foreach ($row as $k => $v) $model->$k = $v;
        return $model;
    }

    // 更新實體
    public function update(Model $model) {
        if (!$model->validate()) return false;
        $data = $model->toArray();
        $id = $data[$model->pk];
        unset($data[$model->pk]);
        $sets = [];
        foreach ($data as $k => $v) $sets[] = "$k = '$v'";
        $sql = "UPDATE {$model->table} SET " . implode(',', $sets) . " WHERE {$model->pk} = $id";
        return $this->db->execute($sql) > 0;
    }

    // 刪除實體
    public function delete($id) {
        $sql = "DELETE FROM {$this->modelClass} WHERE {$this->pk} = $id";
        return $this->db->execute($sql) > 0;
    }
}
?>

4. 具體 Manager:ClassManager

<?php
// Model/ClassManager.php
require_once 'Manager.php';
require_once 'ClassModel.php';

class ClassManager extends Manager {
    protected $modelClass = 'ClassModel';
    protected $pk = 'cls_id';
}
?>

測試腳本範例

<?php
// ModelTest1.php
require_once 'Model/ClassManager.php';
require_once 'Model/StudentManager.php';

$classMgr = new ClassManager();
$studentMgr = new StudentManager();

// 新增班級
$class = new ClassModel();
$class->cls_name = '三年二班';
$class->cls_address = '教學樓 302';
$classId = $classMgr->create($class);
echo "新增班級 ID: $classId<br>";

// 新增學生
$student = new StudentModel();
$student->stu_name = '小明';
$student->stu_clsid = $classId;
$studentMgr->create($student);

// 查詢班級學生
$students = $studentMgr->findByClass($classId);
foreach ($students as $s) {
    echo "學生: {$s->stu_name}<br>";
}
?>

設計精華回顧

  • 關注點分離:資料結構、業務流程、資料存取三層解耦。
  • 可測試性:Manager 依賴 Db 介面,易於 Mock 測試。
  • 擴充彈性:新增實體只需建立 Model + Manager,不動既有代碼。
  • 驗證前置:資料寫入前強制驗證,守護資料完整性。

此架構雖為教學簡化,但已具備生產級 MVC Model 層的核心骨幹,實戰中可根據業務複雜度逐步豐富(如加入快取、事務、事件機制等)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved