0

PHP và MySQL Bài 26: Lên ý tưởng, thiết kế cơ sở dữ liệu (ERD) và phân chia cấu trúc thư mục (MVC thu nhỏ)

Từ Bài 1 đến Bài 25, chúng ta đã viết code theo kiểu "kịch bản thủ tục" (Procedural) – mọi thứ từ HTML, xử lý logic, đến truy vấn SQL đều bị nhét chung vào một file .php duy nhất. Cách làm này chỉ phù hợp để học nền tảng. Trong thực tế, nếu duy trì cách viết đó cho một hệ thống lớn, mã nguồn sẽ trở thành một "đống rác" (Spaghetti code) không thể bảo trì.

Để chuẩn bị cho việc học các Framework chuyên nghiệp (như Laravel), dự án cuối khóa này sẽ được xây dựng dựa trên Mô hình kiến trúc MVC.


1. Ý tưởng dự án: Hệ thống quản trị nội dung (Mini CMS / Blog)

Chúng ta sẽ xây dựng một trang web tin tức/blog cá nhân với hai khu vực tách biệt:

  • Khu vực Client (Giao diện người dùng): Xem danh sách bài viết mới nhất, phân trang, đọc chi tiết bài viết theo danh mục.
  • Khu vực Admin (Trang quản trị): Đăng nhập/Đăng ký an toàn; Thêm, sửa, xóa (CRUD) bài viết và danh mục.

2. Thiết kế Cơ sở dữ liệu (ERD - Entity Relationship Diagram)

Dựa vào ý tưởng trên, chúng ta cần 3 bảng chính với các mối quan hệ (1-N) như sau:

Bảng users (Người dùng/Tác giả)

Lưu trữ thông tin đăng nhập và phân quyền.

  • id: INT, AUTO_INCREMENT, PRIMARY KEY
  • fullname: VARCHAR(50)
  • email: VARCHAR(100), UNIQUE (Không cho phép trùng email đăng ký)
  • password: VARCHAR(255) (Lưu chuỗi băm Bcrypt)
  • role: TINYINT(1) DEFAULT 0 (0: User bình thường, 1: Admin)

Bảng categories (Danh mục bài viết)

  • id: INT, AUTO_INCREMENT, PRIMARY KEY
  • name: VARCHAR(100) (Ví dụ: "Công nghệ", "Lập trình Backend")

Bảng posts (Bài viết)

Liên kết với users (Ai viết bài này?) và categories (Thuộc danh mục nào?).

  • id: INT, AUTO_INCREMENT, PRIMARY KEY
  • title: VARCHAR(255)
  • content: TEXT
  • thumbnail: VARCHAR(255) (Đường dẫn lưu ảnh bìa)
  • user_id: INT, FOREIGN KEY trỏ về users(id)
  • category_id: INT, FOREIGN KEY trỏ về categories(id)
  • created_at: TIMESTAMP DEFAULT CURRENT_TIMESTAMP

Câu lệnh SQL khởi tạo nhanh CSDL:

CREATE DATABASE mini_cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE mini_cms;

-- Tạo bảng users
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    fullname VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    role TINYINT(1) DEFAULT 0
);

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

-- Tạo bảng posts
CREATE TABLE posts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    thumbnail VARCHAR(255),
    user_id INT,
    category_id INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (category_id) REFERENCES categories(id)
);

3. Hiểu về Mô hình MVC (Model - View - Controller)

MVC là một mẫu kiến trúc phần mềm giúp tách biệt các thành phần của ứng dụng thành 3 lớp riêng biệt, ai làm việc nấy:

  • Model (Mô hình Dữ liệu): Chịu trách nhiệm giao tiếp trực tiếp với Database (PDO). Nó thực hiện các câu lệnh SQL để lấy, thêm, sửa, xóa dữ liệu. Model không quan tâm dữ liệu sẽ hiển thị ra sao.
  • View (Giao diện): Là các file chứa mã HTML/CSS. Nhiệm vụ duy nhất của View là nhận dữ liệu đã được xử lý và in ra màn hình cho người dùng xem. View không được chứa logic truy vấn CSDL.
  • Controller (Bộ điều khiển): Là "Bộ não" trung tâm. Khi người dùng click vào một link, Controller sẽ tiếp nhận yêu cầu, gọi Model tương ứng để lấy dữ liệu, sau đó ném dữ liệu đó sang cho View để render thành HTML trả về trình duyệt.

4. Phân chia cấu trúc thư mục dự án

Mở VS Code, tạo một thư mục mới tên là mini-cms (nằm trong htdocs hoặc www của XAMPP/Laragon) và thiết lập cấu trúc cây thư mục cực kỳ chuẩn mực như sau:

/mini-cms
│
├── /assets             # Chứa file tĩnh (Trình duyệt có thể truy cập)
│   ├── /css            # Các file style.css
│   ├── /js             # Các file script.js
│   └── /uploads        # Nơi lưu ảnh do người dùng tải lên (Bài 14)
│
├── /config             # Chứa cấu hình hệ thống
│   └── database.php    # Khởi tạo kết nối PDO (Bài 23)
│
├── /controllers        # Nơi chứa các "Bộ não" xử lý logic
│   ├── AuthController.php   # Xử lý Đăng nhập/Đăng ký
│   └── PostController.php   # Xử lý logic Thêm/Sửa/Xóa bài viết
│
├── /models             # Nơi chứa các file tương tác SQL
│   ├── User.php        # Chứa SQL SELECT/INSERT bảng users
│   └── Post.php        # Chứa SQL bảng posts
│
├── /views              # Nơi chứa giao diện HTML
│   ├── /admin          # Giao diện cho quản trị viên
│   │   ├── dashboard.php
│   │   └── create_post.php
│   ├── /client         # Giao diện cho người đọc
│   │   └── home.php
│   └── layout.php      # Header/Footer dùng chung
│
└── index.php           # Front Controller: Điểm đầu vào duy nhất của hệ thống

Tại sao lại cần file index.php (Front Controller) ở ngoài cùng?

Trong mô hình hiện đại, chúng ta không cho người dùng truy cập trực tiếp vào các file như http://localhost/mini-cms/controllers/PostController.php.

Mọi Request (yêu cầu) đều phải đi qua cánh cửa duy nhất là index.php. Tại đây, hệ thống sẽ đọc URL, kiểm tra bảo mật (Session), và tự động điều hướng (Routing) luồng xử lý vào đúng Controller cần thiết.


Tổng kết

Bản thiết kế đã hoàn thiện, móng nhà đã được đào xong với cấu trúc thư mục rõ ràng. Ở bài học tiếp theo, chúng ta sẽ bắt đầu xây dựng tính năng quan trọng nhất để bảo vệ "ngôi nhà" của mình.

Đó chính là Bài 27: Xây dựng hệ thống Đăng ký, Đăng nhập và Phân quyền cơ bản.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí