NTM Solutions

Bài đăng nổi bật

🚀 Laravel 12 (2026) — Từ PHP Core đến Full Stack📘

Nếu cập nhật theo Laravel 12 LTS (2026) thì mình sẽ chia thành các phần như sau để người học đi từ PHP Core → Laravel → Triển khai dự án th...

Thứ Bảy, 4 tháng 7, 2026

🧩Xây dựng mô hình MVC đơn giản bằng PHP thuần (MySQLi)🐘

Trong ví dụ này, chúng ta xây dựng một ứng dụng PHP theo mô hình MVC (Model - View - Controller) mà không sử dụng framework.

📂 Cấu trúc thư mục

project/
│
├── app/
│   ├── controllers/
│   │   └── ProductController.php
│   │
│   ├── models/
│   │   └── ProductModel.php
│   │
│   └── views/
│       └── home.php
│
├── config/
│   └── Database.php
│
└── public/
    └── index.php

1️⃣ Database

File:

config/Database.php
<?php

class Database
{
    public static function connect()
    {
        return mysqli_connect(
            "localhost",
            "root",
            "",
            "shop_dienthoai"
        );
    }
}

Nhiệm vụ

  • Kết nối MySQL.

  • Trả về đối tượng kết nối.

  • Các Model sẽ dùng chung class này.

p/S: nhớ vào phpMyadmin tạo database shop_dienthoai trước.
-- Tạo database
CREATE DATABASE IF NOT EXISTS shop_dienthoai
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

-- Chọn database
USE shop_dienthoai;

-- Tạo bảng products
CREATE TABLE products (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);

-- Dữ liệu mẫu
INSERT INTO products (name) VALUES
('iPhone 16 Pro Max'),
('Samsung Galaxy S25 Ultra'),
('Xiaomi 15 Pro'),
('OPPO Find X8 Pro'),
('Google Pixel 10');

2️⃣ Model

File:

app/models/ProductModel.php
<?php

class ProductModel
{
    private $conn;

    public function __construct()
    {
        $this->conn = Database::connect();
    }

    public function getAll()
    {
        $result = mysqli_query($this->conn, "SELECT * FROM products");

        $products = [];

        while ($row = mysqli_fetch_assoc($result)) {
            $products[] = $row;
        }

        return $products;
    }
}

Nhiệm vụ

Model chỉ làm việc với dữ liệu.

Trong ví dụ trên:

  • Kết nối database.

  • Thực hiện câu lệnh SQL.

  • Trả về mảng sản phẩm.

Model không hiển thị HTMLkhông xử lý giao diện.


3️⃣ Controller

File:

app/controllers/ProductController.php
<?php

class ProductController
{
    public function index()
    {
        $model = new ProductModel();

        $products = $model->getAll();

        include ROOT . "/app/views/home.php";
    }
}

Nhiệm vụ

Controller là trung gian giữa Model và View.

Quy trình:

  1. Tạo Model.

  2. Gọi Model lấy dữ liệu.

  3. Đưa dữ liệu sang View.

  4. View hiển thị kết quả.

Controller không viết SQLkhông tạo HTML.


4️⃣ View

File:

app/views/home.php
<h1>Danh sách sản phẩm</h1>

<?php foreach($products as $row): ?>

    <p><?= $row["name"] ?></p>

<?php endforeach; ?>

Nhiệm vụ

View chỉ nhận dữ liệu từ Controller rồi hiển thị.

Trong ví dụ này:

  • Không kết nối database.

  • Không chạy SQL.

  • Chỉ lặp mảng $products.


5️⃣ Front Controller

File:

public/index.php
<?php

define('ROOT', dirname(__DIR__));

require_once ROOT . '/config/Database.php';
require_once ROOT . '/app/models/ProductModel.php';
require_once ROOT . '/app/controllers/ProductController.php';

$controller = new ProductController();

$controller->index();

Đây là điểm bắt đầu của toàn bộ ứng dụng.

Nó thực hiện:

  • Khai báo hằng số ROOT.

  • Nạp các class cần thiết.

  • Khởi tạo Controller.

  • Gọi action index().


🔄 Luồng hoạt động của MVC

Trình duyệt
      │
      ▼
public/index.php
      │
      ▼
ProductController
      │
      ▼
ProductModel
      │
      ▼
Database
      │
      ▼
MySQL
      │
      ▼
ProductModel
      │
      ▼
ProductController
      │
      ▼
View (home.php)
      │
      ▼
Hiển thị HTML

📌 Vai trò của từng thành phần

Thành phầnChức năng
DatabaseKết nối MySQL
ModelXử lý dữ liệu
ControllerĐiều phối chương trình
ViewHiển thị giao diện
index.phpĐiểm vào của ứng dụng

Ưu điểm của mô hình MVC

  • Tách biệt giao diện và dữ liệu.

  • Code dễ đọc.

  • Dễ bảo trì.

  • Có thể mở rộng thành Router.

  • Dễ chuyển sang Framework như Laravel hoặc CodeIgniter.


Lưu ý về require_once

Trong ví dụ trên, tất cả các class được nạp thủ công bằng:

require_once ...

Cách này phù hợp với dự án nhỏ, nhưng khi số lượng Controller và Model tăng lên sẽ phát sinh một số bất tiện:

  • Phải tự thêm require_once mỗi khi tạo class mới.

  • Nếu đổi tên file hoặc namespace thì phải sửa nhiều nơi.

  • Một số môi trường (đặc biệt khi dùng OPcache hoặc cấu hình Apache) có thể khiến việc đổi tên file, thêm class hoặc thay đổi đường dẫn chưa được nhận ngay, dẫn đến cảm giác phải Reload/Restart Apache mới hoạt động đúng.

Trong các dự án lớn, người ta thường sử dụng Autoload (ví dụ spl_autoload_register() hoặc Composer PSR-4) để PHP tự động nạp class khi cần. Khi đó, gần như không còn phải viết require_once cho từng Controller hoặc Model nữa và việc phát triển trở nên thuận tiện hơn rất nhiều.

p/S: xem thêm MVC viết theo phong cách API  tại đây.

(chỉ cần link API là phần view lấy được dữ liệu dù bất kỳ ngôn ngữ nào)

x1

quay về MỤC LỤC

Không có nhận xét nào:

Đăng nhận xét

Facebook Youtube RSS