0

EzCode # Phụ lục A — Tra cứu nhanh

Phụ lục A — Tra cứu nhanh

Bảng tra cứu mọi hàm PHP, cú pháp SQL, và thuật ngữ được dùng trong project EzCode. Cột "Bài" cho biết bài học nào dạy nó.

⬅️ Về mục lục


1. Hàm PHP dùng trong project

1.1. In ra và cấu trúc chương trình

Hàm Công dụng Ví dụ trong project Bài
echo In nội dung ra trang echo 'Thành công'; — payment_history.php 1
<?= ?> Dạng rút gọn của <?php echo ?> <?= $course['title'] ?> — mọi View 1
print_r() In cấu trúc mảng để gỡ lỗi Dùng trong bài tập 3
var_dump() In giá trị kèm kiểu dữ liệu Dùng trong bài tập 2
include_once Nạp file một lần duy nhất include_once "./Models/Database.php"; 6
exit() Dừng chương trình ngay Luôn đi sau header() 4
die() Giống exit(), in thêm thông báo Đề xuất trong bản vá lỗi 16 22

1.2. Kiểm tra biến

Hàm Công dụng Ví dụ trong project Bài
isset() Biến có tồn tại và khác null không isset($_SESSION['user_id']) 3
empty() Biến có rỗng không (0, '', [], null đều rỗng) if (empty($errors)) — UserController 3
?? Lấy giá trị, không có thì dùng giá trị thay thế $_POST['name'] ?? '' 4
count() Đếm số phần tử mảng count($teacherCourses) — teacher_dashboard.php 3
is_array() Kiểm tra có phải mảng không Đề xuất thay === false ở lỗi 5 17
is_dir() Thư mục có tồn tại không if (!is_dir($uploadDir)) — TeacherController 18
file_exists() File có tồn tại không Trước khi unlink() ảnh cũ 18

1.3. Chuỗi

Hàm Công dụng Ví dụ trong project Bài
strlen() Đếm số byte strlen($new_password) < 6 — UserController 2
mb_strlen() Đếm số ký tự, đúng với tiếng Việt Đề xuất thay strlen ở Bài 19 19
substr() Cắt chuỗi theo byte substr($lesson['content'], 0, 50) 19
mb_substr() Cắt chuỗi theo ký tự Đề xuất thay substr 19
strtolower() Đổi về chữ thường strtolower($fileInfo['extension']) 18
str_replace() Thay chuỗi con Cắt tiền tố URL YouTube — learn_detail.php 16
str_repeat() Lặp chuỗi nhiều lần str_repeat('?,', count($teachers) - 1) 12
implode() Ghép mảng thành chuỗi implode(", ", $errors) 16
nl2br() Đổi xuống dòng thành <br> Đề xuất cho mô tả khóa học 22
htmlspecialchars() Lọc ký tự HTML, chống XSS htmlspecialchars($_SESSION['user_name']) 14
ucfirst() Viết hoa chữ cái đầu ucfirst($_GET['ctrl']) — index.php 9
preg_match() So khớp biểu thức chính quy Kiểm tra số điện thoại trong bài tập 14
urlencode() Mã hóa chuỗi để đưa vào URL Tạo chữ ký VNPay 21
json_encode() Đổi mảng PHP thành chuỗi JSON <?= json_encode($lessionsList) ?> 16

1.4. Mảng

Hàm Công dụng Ví dụ trong project Bài
in_array() Giá trị có trong mảng không in_array($extension, $allowedExtensions) 11
array_merge() Nối hai mảng array_merge($params, $teachers) — Courses::filter 12
array_column() Rút một cột ra khỏi mảng lồng nhau array_column($teacherCourses, 'price') 17
array_sum() Cộng mọi phần tử Dùng cùng array_column 17
array_slice() Lấy một đoạn của mảng array_slice($teacherCourses, 0, 4) 17
ksort() Sắp xếp mảng theo khóa Bắt buộc trước khi tạo chữ ký VNPay 21
unset() Xóa một phần tử hoặc biến unset($_SESSION['success']) 5

1.5. Số và ngày tháng

Hàm Công dụng Ví dụ trong project Bài
number_format() Định dạng số có dấu ngăn nghìn number_format($course['price']) 2
date() Định dạng ngày giờ date('d/m/Y', ...) — user_course.php 2
strtotime() Đổi chuỗi ngày thành số Luôn đi cùng date() 2
time() Số giây từ 1970 Đặt tên file upload 18
rand() Số ngẫu nhiên rand(1000, 9999) — tạo mã đơn hàng 21
uniqid() Chuỗi định danh duy nhất Đặt tên file upload 18

1.6. Bảo mật

Hàm Công dụng Ví dụ trong project Bài
password_hash() Băm mật khẩu để lưu password_hash($password, PASSWORD_DEFAULT) 14
password_verify() Đối chiếu mật khẩu với chuỗi băm password_verify($password, $user['password']) 15
hash_hmac() Tạo chữ ký có khóa bí mật hash_hmac('sha512', $hashdata, $secret) 21
filter_var() Kiểm tra định dạng dữ liệu filter_var($email, FILTER_VALIDATE_EMAIL) 4

1.7. Session và điều hướng

Hàm Công dụng Ví dụ trong project Bài
session_start() Khởi động phiên làm việc Dòng 6 của index.php 5
session_destroy() Hủy phiên, dùng cho đăng xuất UserController::logout() 5
session_id() Lấy mã phiên hiện tại Dùng trong bài tập 5
setcookie() Đặt cookie Bài tập ghi nhớ email 15
header() Gửi lệnh HTTP, thường để chuyển hướng header("Location: ?ctrl=user&act=login") 4
ob_start() Bật bộ đệm đầu ra Bản vá lỗi 13 22
ob_get_clean() Lấy nội dung đệm và tắt bộ đệm Bản vá lỗi 13 22

1.8. File và upload

Hàm Công dụng Ví dụ trong project Bài
pathinfo() Tách đường dẫn thành các phần Lấy phần mở rộng file ảnh 18
mkdir() Tạo thư mục mkdir($uploadDir, 0755, true) 18
move_uploaded_file() Chuyển file tải lên tới đích Bắt buộc dùng cho upload 18
unlink() Xóa file Xóa ảnh cũ khi đổi ảnh mới 18
getimagesize() Đọc kích thước ảnh, xác thực file thật là ảnh Đề xuất trong bài tập 18
glob() Lấy danh sách file theo mẫu Script kiểm tra XSS 22
error_log() Ghi thông báo vào file log Đề xuất trong bản vá lỗi 16 22

1.9. Cấu hình và gỡ lỗi

Hàm Công dụng Ví dụ trong project Bài
error_reporting() Chọn mức lỗi được báo cáo error_reporting(E_ALL) — index.php 1
ini_set() Đổi cấu hình PHP lúc chạy ini_set('display_errors', 1) 1
phpversion() Lấy phiên bản PHP Dùng trong bài tập 1
dirname() Lấy thư mục cha của đường dẫn Bản vá lỗi 12 21

2. Biến toàn cục

Biến Chứa gì Khóa hay dùng Bài
$_GET Tham số trên URL ctrl, act, id, keyword, teacher[], category[], sort 4
$_POST Dữ liệu form gửi bằng POST name, email, password, title, price... 4
$_FILES File tải lên image với các khóa con name, tmp_name, error, size 18
$_SESSION Dữ liệu phiên, lưu trên máy chủ user_id, user_name, user_role, success, error 5
$_COOKIE Cookie, lưu ở trình duyệt PHPSESSID do PHP tự quản lý 5
$_SERVER Thông tin về yêu cầu REQUEST_METHOD, HTTP_HOST, REMOTE_ADDR, SCRIPT_NAME, HTTPS 4

3. Cú pháp SQL dùng trong project

3.1. Truy vấn dữ liệu

Cú pháp Công dụng Ví dụ trong project Bài
SELECT * Lấy mọi cột SELECT * FROM categories 8
SELECT c.* Lấy mọi cột của một bảng SELECT c.*, u.name AS teacher_name 13
WHERE Lọc dòng WHERE status = 1 8
AND OR Nối nhiều điều kiện WHERE c.teacher_id = ? AND e.role = 'student' 12
LIKE So khớp theo mẫu WHERE c.title LIKE ? với %tuKhoa% 12
IN (...) Giá trị nằm trong danh sách WHERE c.teacher_id IN (?,?,?) 12
BETWEEN Nằm trong khoảng Bài tập lọc theo giá 12
ORDER BY Sắp xếp, ASC tăng DESC giảm ORDER BY sort_order ASC, id ASC 13
LIMIT Giới hạn số dòng LIMIT 12, LIMIT 5 20
AS Đặt bí danh cho cột u.name AS teacher_name 13

3.2. Nối bảng

Cú pháp Công dụng Ví dụ trong project Bài
INNER JOIN ... ON Nối hai bảng, chỉ giữ dòng khớp cả hai bên INNER JOIN users u ON c.teacher_id = u.id 13
LEFT JOIN Giữ mọi dòng bảng trái Đề xuất thay subquery 17
Bí danh bảng Viết tắt tên bảng FROM courses c 13

3.3. Nhóm và thống kê

Cú pháp Công dụng Ví dụ trong project Bài
COUNT(*) Đếm số dòng SELECT COUNT(*) as total FROM courses 11
COUNT(DISTINCT c) Đếm số giá trị khác nhau COUNT(DISTINCT e.user_id) 19
SUM() Cộng, trả NULL nếu không có dòng SUM(e.price) as total 20
MAX() / MIN() Giá trị lớn nhất / nhỏ nhất MAX(e.enrolled_at) as last_enrollment 19
GROUP BY Gom dòng thành nhóm GROUP BY u.id 19
HAVING Lọc theo cột tính toán Đề xuất trong bài tập 20
DATE_FORMAT() Định dạng ngày để gom nhóm DATE_FORMAT(e.enrolled_at, '%Y-%m') 20
Subquery trong SELECT Truy vấn con chạy cho mỗi dòng (SELECT COUNT(*) FROM enrollments WHERE ...) 17

3.4. Thay đổi dữ liệu

Cú pháp Công dụng Ví dụ trong project Bài
INSERT INTO ... VALUES Chèn dòng mới INSERT INTO users (...) VALUES (?, ?, ?, ?, ?) 14
UPDATE ... SET ... WHERE Sửa dòng UPDATE users SET name=?, email=? WHERE id=? 16
DELETE FROM ... WHERE Xóa dòng DELETE FROM courses WHERE id=? 18
NOW() Thời điểm hiện tại VALUES (?, ?, ?, NOW()) 21

⚠️ Câu UPDATE hoặc DELETE thiếu WHERE sẽ tác động lên TOÀN BỘ bảng. Không hoàn tác được.

3.5. Định nghĩa bảng

Cú pháp Công dụng Bài
CREATE TABLE Tạo bảng 7
PRIMARY KEY Khóa chính, không trùng và không NULL 7
PRIMARY KEY (a, b) Khóa chính ghép hai cột 7
AUTO_INCREMENT Tự đánh số tăng dần 7
FOREIGN KEY ... REFERENCES Khóa ngoại, ràng buộc liên bảng 7
ON DELETE CASCADE Xóa lan truyền sang bảng con 7
UNIQUE KEY Không cho giá trị trùng 7
ENUM(...) Chỉ nhận các giá trị liệt kê sẵn 7
DEFAULT Giá trị mặc định khi không điền 7

4. Bảng định tuyến đầy đủ

Mọi cặp ctrl và act của project. Địa chỉ đầy đủ có dạng http://localhost/EZCode_khoahoc/?ctrl=...&act=...

4.1. Trang chung

Địa chỉ Phương thức Cần đăng nhập Cần là giảng viên Bài
?ctrl=page&act=home PageController::home() Không Không 10
Địa chỉ trống PageController::home() Không Không 10

4.2. Khóa học

Địa chỉ Phương thức Cần đăng nhập Cần là giảng viên Bài
?ctrl=course&act=list CourseController::list() Không Không 11
?ctrl=course&act=detail&id=N CourseController::detail($id) Không Không 13
?ctrl=course&act=register&id=N CourseController::register($id) Có Không 21

4.3. Người dùng

Địa chỉ Phương thức Cần đăng nhập Cần là giảng viên Bài
?ctrl=user&act=register UserController::register() Không Không 14
?ctrl=user&act=login UserController::login() Không Không 15
?ctrl=user&act=logout UserController::logout() Không Không 15
?ctrl=user&act=profile UserController::profile() Có Không 16
?ctrl=user&act=updateProfile UserController::updateProfile() Có Không 16
?ctrl=user&act=changePassword UserController::changePassword() Có Không 16
?ctrl=user&act=course UserController::course() Có Không 16
⚠️ ?ctrl=user&act=password KHÔNG TỒN TẠI — lỗi số 4 — — 22

4.4. Học tập

Địa chỉ Phương thức Cần đăng nhập Cần là giảng viên Bài
?ctrl=learn&act=detail&id=N LearnController::detail($id) Có Không 16

⚠️ Địa chỉ này không kiểm tra đã mua khóa học — lỗi số 11. Bản vá ở Bài 22.

4.5. Giảng viên

Mọi địa chỉ dưới đây được TeacherController::__construct() bảo vệ: bắt buộc đăng nhập và vai trò teacher.

Địa chỉ Phương thức Bài
?ctrl=teacher&act=dashboard dashboard() 17
?ctrl=teacher&act=courses courses() 17
?ctrl=teacher&act=createCourse createCourse() 18
?ctrl=teacher&act=editCourse&id=N editCourse($id) 18
?ctrl=teacher&act=deleteCourse&id=N deleteCourse($id) 18
?ctrl=teacher&act=manageLessons&id=N manageLessons($course_id) 19
?ctrl=teacher&act=createLesson&id=N createLesson($course_id) 19
?ctrl=teacher&act=students students() — mọi học viên 19
?ctrl=teacher&act=students&id=N students($course_id) — theo khóa 19
?ctrl=teacher&act=analytics analytics() 20
⚠️ ?ctrl=teacher&act=editLesson&id=N KHÔNG TỒN TẠI — lỗi số 2 22
⚠️ ?ctrl=teacher&act=deleteLesson&id=N KHÔNG TỒN TẠI — lỗi số 3 22

⚠️ manageLessons và createLesson nhận tham số tên $course_id, nhưng router chỉ truyền được $_GET['id']. Liên kết dùng course_id= sẽ chết — lỗi số 1. Trước khi vá, hãy gõ tay id= thay vì course_id=.

4.6. Thanh toán

Mọi địa chỉ dưới đây được PaymentController::__construct() bảo vệ: bắt buộc đăng nhập.

Địa chỉ Phương thức Bài
?ctrl=payment&act=create&id=N create($courseId) 21
?ctrl=payment&act=callback callback() — VNPay gọi về 21
?ctrl=payment&act=history history() 21
?ctrl=payment&act=cancel&id=ORDER_... cancel($orderId) 21

5. Cấu trúc 6 bảng database

users — Học viên và giảng viên chung một bảng

Cột Kiểu Ghi chú
id int(11) Khóa chính, AUTO_INCREMENT
name varchar(225) Cho phép NULL
email varchar(225) Cho phép NULL, không có ràng buộc UNIQUE
password varchar(225) Lưu chuỗi băm 60 ký tự
phone varchar(10) Kiểu chuỗi để giữ số 0 đầu
role enum('teacher','student') Mặc định student

categories — Danh mục khóa học

Cột Kiểu Ghi chú
id int(11) Khóa chính, AUTO_INCREMENT
name varchar(225) 33 dòng dữ liệu mẫu

courses — Bảng trung tâm

Cột Kiểu Ghi chú
id int(11) Khóa chính, AUTO_INCREMENT
teacher_id int(11) Khóa ngoại tới users.id
category_id int(11) Khóa ngoại tới categories.id
title varchar(225)
description text Cho phép NULL
price int(11) Đơn vị đồng, không có phần lẻ
image varchar(255) Lưu tên file, không lưu ảnh
status tinyint(4) 1 hiện, 0 ẩn

lessions — Bài học (tên viết sai chính tả của lessons)

Cột Kiểu Ghi chú
id int(11) Khóa chính, AUTO_INCREMENT
course_id int(11) Khóa ngoại tới courses.id
title varchar(225)
video text Mã hoặc địa chỉ video, dữ liệu mẫu không nhất quán
content text
sort_order int(11) Mặc định 999, số nhỏ hiển thị trước

enrollments — Bảng trung gian, ai được học khóa nào

Cột Kiểu Ghi chú
user_id int(11) Khóa ngoại tới users.id
course_id int(11) Khóa ngoại tới courses.id
role enum('teacher','student','') Mặc định student
price int(11) Giá tại thời điểm mua
enrolled_at datetime Mặc định thời điểm hiện tại

Khóa chính ghép (user_id, course_id) — một người không đăng ký trùng một khóa hai lần. Không có cột id.

payments — Lịch sử giao dịch VNPay

Cột Kiểu Ghi chú
id int(11) Khóa chính, AUTO_INCREMENT
order_id varchar(50) UNIQUE, dạng ORDER_YmdHis_XXXX
amount decimal(10,2) Có phần lẻ, khác courses.price
course_id int(11) Khóa ngoại, có ON DELETE CASCADE
user_id int(11) Khóa ngoại, có ON DELETE CASCADE
status enum('pending','completed','failed','cancelled') Mặc định pending
transaction_id varchar(100) Mã giao dịch do VNPay trả về
created_at timestamp Tự điền
updated_at timestamp Tự cập nhật mỗi lần sửa

6. Thuật ngữ Anh-Việt

Thuật ngữ Nghĩa Bài
MVC Model-View-Controller, mô hình chia code thành ba tầng 9
Model Tầng nói chuyện với database 9
View Tầng hiển thị, sinh ra HTML 9
Controller Tầng điều phối giữa Model và View 9
Front controller Bộ điều phối đầu vào, mọi request đi qua một file 9
Middleware Lớp trung gian chạy trước mọi yêu cầu 17
CRUD Create-Read-Update-Delete, bốn thao tác cơ bản với dữ liệu 18
PDO PHP Data Objects, thư viện kết nối database 8
DSN Data Source Name, chuỗi mô tả kết nối database 8
Prepared statement Câu lệnh chuẩn bị sẵn, tách lệnh khỏi dữ liệu 8
Placeholder Chỗ giữ sẵn, dấu ? trong câu SQL 8
SQL Injection Tấn công chèn lệnh SQL qua ô nhập 8
XSS Cross-Site Scripting, chèn mã JavaScript qua dữ liệu 22
Whitelist Danh sách trắng, chỉ cho qua những gì được liệt kê 12
Blacklist Danh sách đen, chặn những gì được liệt kê 18
Session Phiên làm việc, dữ liệu lưu trên máy chủ 5
Cookie Mẩu dữ liệu lưu ở trình duyệt 5
Flash message Thông báo hiện đúng một lần rồi tự mất 5
PRG Post-Redirect-Get, chuyển hướng sau khi xử lý POST 16
Authentication Xác thực, trả lời "bạn là ai" 15
Authorization Phân quyền, trả lời "bạn được làm gì" 15
Hash Chuỗi băm, kết quả một chiều từ dữ liệu gốc 14
Salt Muối, chuỗi ngẫu nhiên trộn vào trước khi băm 14
HMAC Mã xác thực có khóa bí mật 21
Primary key Khóa chính, phân biệt từng dòng 7
Foreign key Khóa ngoại, trỏ tới khóa chính bảng khác 7
Alias Bí danh, tên viết tắt cho bảng hoặc cột 13
Subquery Truy vấn con nằm trong truy vấn khác 17
Vấn đề N+1 Chạy N truy vấn phụ trong vòng lặp thay vì gộp làm một 11
Singleton Mẫu bảo đảm một class chỉ có một object duy nhất 22
Dead code Code chết, được viết ra nhưng không bao giờ chạy 22
Output buffering Bộ đệm đầu ra, giữ nội dung trong bộ nhớ trước khi gửi 22

7. Lỗi hay gặp và cách xử lý

Thông báo Nguyên nhân thường gặp Cách sửa
Parse error: syntax error, unexpected ... Thiếu ; hoặc } hoặc dấu nháy Kiểm tra dòng được báo và dòng ngay trên nó
Parse error: unexpected end of file Thiếu dấu đóng ngoặc hoặc đóng nháy Rà từ cuối file ngược lên
Fatal error: Class "X" not found Quên include_once file chứa class Thêm dòng include ở đầu file
Fatal error: Cannot declare class X Dùng include thay vì include_once Đổi sang include_once
Fatal error: Call to undefined method X::y() Gõ sai tên hoặc phương thức chưa viết Kiểm tra chính tả, hoặc viết phương thức
Fatal error: Uncaught ArgumentCountError Gọi hàm thiếu tham số bắt buộc Tên tham số trên URL phải là id — xem lỗi số 1
Warning: include(): Failed opening ... Sai đường dẫn hoặc file chưa tạo Đường dẫn tính từ index.php, viết ./Models/...
Warning: Undefined variable $x Controller quên gán biến trước khi nạp View Kiểm tra lại Controller
Warning: Undefined array key "x" Gõ sai tên cột, hoặc truy vấn không lấy cột đó So tên khóa với tên cột trong database
Warning: Trying to access array offset on value of type bool Truy vấn trả về false mà không kiểm tra Thêm if (!$ketQua) { ... }
Warning: Cannot modify header information - headers already sent Gọi header() sau khi đã in nội dung Thêm ob_start() — xem lỗi số 13
Connection failed: SQLSTATE[HY000] [1049] Unknown database Chưa tạo database hoặc sai tên Tạo database tên ezcode trong phpMyAdmin
Connection failed: SQLSTATE[HY000] [2002] MySQL chưa chạy Bật MySQL trong XAMPP Control Panel
SQLSTATE[42S02]: Base table ... doesn't exist Chưa import ezcode.sql Làm lại Bài 7
SQLSTATE[HY093]: Invalid parameter number Số dấu ? không khớp số tham số truyền vào Đếm lại từng dấu ? và từng giá trị
SQLSTATE[23000]: Integrity constraint violation: 1451 Xóa dòng đang bị bảng khác tham chiếu Xóa dữ liệu liên quan trước, hoặc thêm ON DELETE CASCADE
SQLSTATE[HY000] [1040] Too many connections Mở quá nhiều kết nối MySQL Áp dụng Singleton — xem lỗi số 16
str_repeat(): Argument #2 must be greater than or equal to 0 Mảng rỗng lọt vào khối sinh dấu ? Bọc bằng if (!empty($mang))
Trang trắng hoàn toàn Lỗi bị giấu Kiểm tra error_reporting(E_ALL) ở đầu index.php
Chữ tiếng Việt thành ký tự lạ Sai bảng mã Kiểm tra <meta charset="UTF-8"> và collation utf8mb4
Ảnh khóa học bị vỡ Đường dẫn không nhất quán Xem lỗi số 17
Bấm lọc xong về trang chủ Form GET thiếu ô ẩn ctrl và act Xem Bài 11 mục 2.6
$_FILES rỗng dù đã chọn file Form thiếu enctype="multipart/form-data" Thêm thuộc tính đó vào thẻ form

⬅️ Về mục lục · Bài 22 — Săn lỗi và vá bảo mật


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.