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.
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ị HTML và khô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:
Tạo Model.
Gọi Model lấy dữ liệu.
Đưa dữ liệu sang View.
View hiển thị kết quả.
Controller không viết SQL và khô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ần | Chức năng |
|---|---|
| Database | Kết nối MySQL |
| Model | Xử lý dữ liệu |
| Controller | Điều phối chương trình |
| View | Hiể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_oncemỗ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.




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