Chào mừng đến với hướng dẫn và ví dụ về ứng dụng MVC với PHP và MySQL. Bạn có thể đã nghe đến MVC ở khắp mọi nơi dưới nhiều hình thức khác nhau - Framework, mẫu thiết kế, khái niệm, kiến trúc, và nhiều hơn thế nữa. Vậy nó là gì? Nó làm gì và ý nghĩa của nó là gì? Làm sao để chúng ta xây dựng một ứng dụng PHP dựa trên MVC!?
Vâng, thực ra nó rất đơn giản. Nhưng như một số người trong ngành công nghệ thích làm, họ làm cho những điều đơn giản trông phức tạp. Hãy cùng đi qua một ví dụ đơn giản trong hướng dẫn này - Tiếp tục đọc!
TỔNG QUAN NỘI DUNG
TẢI MÃ NGUỒN VÍ DỤ
Mã nguồn trên GitHub Gist
Chỉ cần nhấp vào "tải xuống zip" hoặc clone repository. Tôi đã phát hành mã dưới giấy phép MIT, vì vậy bạn có thể thoải mái xây dựng trên nền tảng đó hoặc sử dụng nó trong dự án của riêng bạn.
LỖI QUẢNG CÁO...
Nhưng có ai đó phải trả tiền cho hóa đơn và các nhà tài trợ đang trả tiền cho nó. Tôi nhấn mạnh rằng Code Boxx không trở thành một "doanh nghiệp mã trả phí" và tôi không "chặn những người sử dụng Adblock". Mọi sự hỗ trợ nhỏ cũng có ý nghĩa.
BẢNG & DỮ LIỆU GIẢ
CREATE TABLE users
(
id
bigint(20) NOT NULL,
name
varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE users
ADD PRIMARY KEY (id
), ADD KEY name
(name
);
INSERT INTO users
(id
, name
)
VALUES (1, 'John Doe'), (2, 'Jane Doe'), (3, 'Rusty Terry'), (4, 'Peers Sera'), (5, 'Jaslyn Keely');
Đầu tiên, đây là bảng người dùng giả mà chúng ta sẽ sử dụng. Rất trực tiếp chỉ với ID người dùng và tên.
PHẦN 1) MÔ HÌNH (CƠ SỞ DỮ LIỆU)
class DB {
// (A) KẾT NỐI ĐẾN CƠ SỞ DỮ LIỆU
public $error = "";
private $pdo = null;
private $stmt = null;
function __construct () {
$this->pdo = new PDO(
"mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET,
DB_USER, DB_PASSWORD, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
);
}
// (B) ĐÓNG KẾT NỐI
function __destruct () {
if ($this->stmt!==null) { $this->stmt = null; }
if ($this->pdo!==null) { $this->pdo = null; }
}
// (C) CHẠY TRUY VẤN SELECT
function select ($sql, $data=null) {
$this->stmt = $this->pdo->prepare($sql);
$this->stmt->execute($data);
return $this->stmt->fetchAll();
}
}
// (D) CÀI ĐẶT CƠ SỞ DỮ LIỆU - THAY ĐỔI THÀNH CỦA BẠN!
define("DB_HOST", "localhost");
define("DB_NAME", "test");
define("DB_CHARSET", "utf8mb4");
define("DB_USER", "root");
define("DB_PASSWORD", "");
// (E) ĐỐI TƯỢNG CƠ SỞ DỮ LIỆU MỚI
$_DB = new DB();
Model đề cập đến cấu trúc dữ liệu. Vậy trong trường hợp ứng dụng PHP-MYSQL của chúng ta, "mô hình" của chúng ta sẽ là một lớp cơ sở dữ liệu xử lý tất cả "điều tương tác với cơ sở dữ liệu" - Kết nối với cơ sở dữ liệu, quản lý kết nối và thực hiện các truy vấn SQL.
PHẦN 2) BỘ ĐIỀU KHIỂN (XỬ LÝ)
// (A) KẾT NỐI CƠ SỞ DỮ LIỆU
require "1-model.php";
// (B) TÌM KIẾM NGƯỜI DÙNG
$results = $_DB->select(
"SELECT * FROM `users` WHERE `name` LIKE ?",
["%{$_POST["search"]}%"]
);
// (C) HIỂN THỊ KẾT QUẢ
echo json_encode(count($results)==0 ? null : $results);
Bộ điều khiển là một "sự trung gian" kết nối giữa đầu vào của người dùng và mô hình. Trong trường hợp này, đó sẽ là một điểm cuối(endpoint) chấp nhận $_POST["search"] từ người dùng, sử dụng mô hình (cơ sở dữ liệu) để tìm kiếm và trả về kết quả.
PHẦN 3) GIAO DIỆN NGƯỜI DÙNG (VIEW)
![PHP MVC With Database (Very Simple Beginner Example)](https://nanado.edu.vn/uploads/images/blog/admin/2024/02/13/php-mvc-with-database-very-simple-beginner-example-1707764278.webp)
Cuối cùng, giao diện người dùng nên tự nhiên và dễ hiểu. Nó không hơn gì HTML, CSS, Javascript để tạo giao diện người dùng.
## CÁCH LÀM "KHÔNG ĐÚNG"
PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
);
// (B3) TÌM KIẾM
$stmt = $pdo->prepare("SELECT * FROM `users` WHERE `name` LIKE ?");
$stmt->execute(["%{$_POST["search"]}%"]);
$results = $stmt->fetchAll();
// (B4) HIỂN THỊ
if (count($results)>0) {
foreach ($results as $r) {
echo "{$r["id"]} - {$r["name"]}";
}
}
}
?>
Đối với những người vẫn còn bối rối, có lẽ một ví dụ tiêu cực về "không tốt về MVC" sẽ giúp ích - Đặt tất cả các thành phần MVC vào một đoạn mã kịch bản duy nhất.
## ĐIỂM CHÚ Ý - TỐT & XẤU?
Thực ra, không có gì sai khi đặt tất cả mọi thứ vào một tệp duy nhất. Điều này thuận tiện hơn và dễ dàng hơn cho các dự án nhỏ làm điều đó. Nhưng nếu bạn nghĩ về nó theo "thực sự về MVC", cơ sở dữ liệu (mô hình), lấy dữ liệu (bộ điều khiển) và hiển thị dữ liệu (giao diện người dùng) đều nằm trong một tệp duy nhất.
Đó không phải là những gì chúng ta muốn trong MVC. Ý tưởng chung của MVC là có một sự phân tách rõ ràng của các thành phần và có các tệp duy nhất xử lý từng thành phần. Ví dụ, kịch bản xử lý mô hình dữ liệu nên nằm trong một tệp riêng biệt, bộ điều khiển trong một tệp riêng biệt và giao diện người dùng HTML trong một tệp khác.
## KHÔNG CHỈ CÓ CÁCH DUy NHẤT
Tôi đã nghe những "những người chuyên gia code troll" la lên - Đây không phải là MVC! MVC phải có định dạng của site.com/MODEL/ site.com/VIEW/ site.com/CONTROLLER/. Vâng, hãy tuân thủ ý tưởng "cố định về cách MVC phải là". Điều đó không sai, nhưng hãy đưa ra lập luận tốt hơn. Các ninja code chân thực hiểu rõ hơn - MVC là một khái niệm trừu tượng.
Cách bạn thiết kế một hệ thống xung quanh MVC hoàn toàn thuộc về bạn. Hướng dẫn này chỉ là một ví dụ đơn giản về vô số khả năng. Ngay cả "ví dụ không đúng" ở trên cũng là MVC, chỉ là tất cả 3 thành phần nằm trong một tệp duy nhất; Chúng ta có thể tạo ra 3 hàm riêng và vẫn gọi nó là "MVC" - Một để kết nối cơ sở dữ liệu, một để thực hiện tìm kiếm và một để vẽ HTML.
## LIÊN KẾT & REFERENCE
- [Model-view-controller - Wikipedia](https://vi.wikipedia.org/wiki/Model-view-controller)