Mini Project sử dụng PHP với MVC

Các bạn đã học xong phần lý thuyết MVC, giờ chúng ta cùng đến với một mini project sử dụng PHP, MySQL, OOP và MVC nhé để cho rõ hơn nhé.

1. Code mẫu

Dự án minh họa


Trong bài này chúng ta sẽ làm một ứng dụng web minh họa quản lý học sinh đơn giản:



Thiết kế cơ sở dữ liệu

Đầu tiên ta cần tạo một database có tên students
Trong database có tên students, chúng ta tạo một bảng students như bên dưới



Tổ chức chương trình và source code

– Đầu tiên ta cần có 1 điểm truy cập ban đầu để vào được ứng dụng, file index.php đảm nhận nhiệm vụ này. “Cổng vào” ban đầu này sẽ đóng vai trò hiển thị hết những tính năng mà ứng dụng có, và cho người dùng truy cập vào chức năng mong muốn (controller tương ứng), ở đây để đơn giản thì ta chỉ cài đặt 1 chức năng là “quản lí học sinh”. (Ta vẫn có thể truy cập trực tiếp vào từng chức năng cụ thể ở các file controller)

– Trong ví dụ tới này, mình sẽ tổ chức source code minh hoạ như mô hình sau đây:



Trước khi vào code các phần MVC, chúng ta phải xử lý một chút ở file index.php trước đã: Đây sẽ là trang đầu tiên, có điều hướng đến Controller xử lý chức năng quản lý học sinh:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>MVC_Webbynat</title>
</head>

<body>
    <h1>Vi du ve mo hinh MVC</h1>
    
    <h3>Chuc nang:</h3>
    <h3>1. <a href="Controller/StudentController.php">Quan li hoc sinh</a></h3>
</body>
</html>

a. Tầng Controller

Tầng Controller sẽ sử dụng để điều hướng dữ liệu. Trong mini project này, tầng controller sẽ điều hướng xem chi tiết sinh viên hay là xem danh sách sinh viên. Tiếp theo sẽ gọi Model và load view tương ứng để lấy dữ liệu hiển thị ra cho người dùng

<?php

include_once("../Model/StudentModel.php");

//1. Declaration
/**
 * Định nghĩa Class StudentController
 */
class  StudentController
{
    /**
     * Định nghĩa hàm 
     */
    public function invoke(){
                if(isset($_GET['stid'])) { // Check nếu có student id thì load view xem detail
            $modelStudent =  new StudentModel();
            $student = $modelStudent->detail($_GET['stid']);
            
            include_once("../View/StudentDetail.html");
        } else { // Check nếu không có studen id thì load view xem danh sách

            $modelStudent =  new StudentModel();
            $studentList = $modelStudent->list();
            
            include_once("../View/StudentList.html");
        }
    }
};


//////////////////////////////////////
//2. Process
// Khởi tạo StudenController và chạy 
$studentController = new StudentController();
$studentController->invoke();
 


b. Tạo Connection, tầng Model và các lớp thực thể (Entity class)

- Connection: Trước tiên chúng ta sẽ định nghĩa config cho database và một class để handle việc kết nối vào trong Database.
Tạo file Config lưu thông tin kết nối: Trong folder Config, tạo 1 file là database.php


<?php
/**
 * Tạo file config để lưu các thông tin cấu hình database
 */
return [
    'host' => '127.0.0.1',
    'username' => 'root',
    'password' => '',
    'database' => 'students'
];

Nội dung của file config này sẽ được sử dụng trong class Connection.


<?php
/**
 * Class để kết nối cơ sở dữ liệu
 */
Class Connection {
    public $connection;
    public function __construct() 
    {
        // Load mảng cấu hình vào biến $config
        $config = include('../Config/database.php');
        // Kết nối cơ sở dữ liệu
        $this->connection = mysqli_connect(
            $config['host'], 
            $config['username'], 
            $config['password'], 
            $config['database']);
        // Cấu hình charset utf8 cho kết nối để đảm bảo không lỗi font khi lấy dữ liệu từ db ra
        $this->connection->set_charset('utf8');
        
        if (!$this->connection) {
            echo "Lỗi kết nối tới MySQL: ".mysqli_connect_error();
            exit;
        }
    }
}


- Entity Class: Entity là một thực thể, ở đây sẽ đại diện cho thực thể Student

<?php

class StudentEntity
{
    public $id;
    public $name;
    public $age;
    public $university;
    
    public function __construct($_id, $_name, $_age, $_university)
    {
        $this->id = $_id;
        $this->name = $_name;
        $this->age = $_age;
        $this->university = $_university;
    }
}


- Model Class:
Chúng ta sẽ có một Model cha, sử dụng abstract để định nghĩa các method mà các model con kế thừa nó cũng cần phải có:

<?php
include_once("Connection.php");
abstract Class Model {
    protected $connection;

    protected function __construct() {
        // Khởi tạo Object Connection để sử dụng
        $connection = new Connection();
        // Gán connection được khởi tạo bởi Object Connection vào property của StudentModel để sử dụng
        $this->connection = $connection->connection;
    }

    abstract public function list();
 
    abstract public function detail($id);
}

StudentModel sẽ sử dụng StudentEntity và có các method được định nghĩa trong  để lấy dữ liệu từ cơ sở dữ liệu và biến đổi thành dữ liệu dùng được ở controller và view
 

<?php
include_once("Model.php");
include_once("StudentEntity.php");

class StudentModel extends Model
{
    public function __construct() 
    {
        return parent::__construct();
    }
    
    public function list() 
    {
        $query = 'SELECT * FROM students';
        $results = $this->connection->query($query);
        $students = [];
        // Biến đổi dữ liệu lấy ra từ cơ sở dữ liệu thành dạng mảng dễ sử dụng
        while ($row = mysqli_fetch_assoc($results)) {
            $students[$row['id']] = new StudentEntity($row['id'], $row['name'], $row['age'], $row['university']);
        }
        // Trả về giá trị cuối cùng
        return $students;
    }
    
    public function detail($id
    {
        //Gia su rang ta load data tu CSDL
        $allStudent = $this->list();
        return $allStudent[$id];
    }
}

c. Tầng View

Ở trong mini project này, chúng ta sẽ có 2 view, 1 để thể hiện dữ liệu chi tiết của sinh viên, 2 là để thể hiện dữ liệu dạng danh sách sinh viên. Phần này sẽ được điều hướng từ phía Controller

File view chi tiết 1 sinh viên:


<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8"/>
    <title>Chi tiet hoc sinh</title>
</head>

<body>
    <h2>Chi tiet hoc sinh:</h2>
    
    <?php
    
        echo  "<p><b>" .$student->name ."</b></p>";
        echo "<p> Age: " .$student->age .", School: " .$student->university .".</p><br>";
        
    ?>
    
    <p><a href="javascript:history.back()">Back</a></p>
    
</body>
</html>
 


File view danh sách sinh viên:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Danh sach hoc sinh</title>
</head>

<body>
    <h2>Danh sach hoc sinh:</h2>

    <?php
    
        for($i = 1; $i <= sizeof($studentList); $i++)
        {
            echo  "<p>" .$i .". <a href='?stid=" .$studentList[$i]->id ."'>" .$studentList[$i]->name ."</a></p>";
        }
        
    ?>

        <br>
        <p><a href="../index.php">Home page</a></p>
</body>

</html>

2. Kết luận

– Mô hình MVC là mô hình thông dụng và tiện lợi hàng đầu trong việc phát triển ứng dụng web, trên đây trình bày cơ bản về mô hình MVC và các thức của nó hoạt động, các framework khác cũng sẽ tạo ra mô hình MVC với cấu trúc gần tương tự như trên.

– Một vài lợi điểm của MVC:

  • Tách biệt Model và View, tạo sự linh hoạt khi thay đổi ứng dụng (giao diện, xử lí, …)
  • Team work tốt hơn trong một dự án do Model, View, Controller là tách biệt
  • Tầng Model và View có thể thay đổi, chỉnh sửa 1 cách độc lập. Ta có thể tạo các ứng dụng giao tiếp thông minh hơn chỉ bằng cách thay đổi View, hoặc cũng có thể thay thế Database bằng các sử dụng Web service, …