Bai11) */ require_once __DIR__ . '/../db_config.php'; require_once __DIR__ . '/lab04_helper.php'; $dbConnected = false; $dbError = null; $studentCount = 0; $actionMessage = ''; try { $pdo = getPdoConnection(); if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'reset_db') { ensureLab04StudentsTable($pdo, true); $actionMessage = 'Đã khởi tạo lại bảng students và nạp mới 12 bản ghi dữ liệu mẫu thành công!'; } else { ensureLab04StudentsTable($pdo, false); } $studentCount = (int)$pdo->query("SELECT COUNT(*) FROM `students`")->fetchColumn(); $dbConnected = true; } catch (Throwable $e) { $dbError = $e; } $exercises = [ [ 'code' => 'Bai01', 'title' => 'Bài 01: Kết nối MySQL với PDO', 'desc' => 'Thiết lập kết nối PDO tới CSDL labdb, kiểm tra trạng thái kết nối, phiên bản MySQL Server và cấu hình UTF-8.', 'files' => ['Bai01/database.sql', 'Bai01/connect.php', 'Bai01/index.php'], 'badge' => 'PDO Connection' ], [ 'code' => 'Bai02', 'title' => 'Bài 02: Tạo bảng students & Dữ liệu mẫu', 'desc' => 'Tạo bảng students (id, name, email, phone, birthday, created_at) và nạp 12 bản ghi sinh viên mẫu.', 'files' => ['Bai02/students.sql', 'Bai02/connect.php', 'Bai02/index.php'], 'badge' => 'DDL & Seed Data' ], [ 'code' => 'Bai03', 'title' => 'Bài 03: Hiển thị danh sách sinh viên', 'desc' => 'Truy vấn SELECT dữ liệu từ bảng students bằng PDO và hiển thị ra bảng HTML chuẩn Bootstrap 5.', 'files' => ['Bai03/students.sql', 'Bai03/list_students.php', 'Bai03/index.php'], 'badge' => 'SELECT Query' ], [ 'code' => 'Bai04', 'title' => 'Bài 04: Thêm sinh viên mới (INSERT)', 'desc' => 'Tạo form nhập sinh viên mới, kiểm tra dữ liệu hợp lệ và lưu vào CSDL bằng PDO Prepared Statement.', 'files' => ['Bai04/students.sql', 'Bai04/add_student.php', 'Bai04/index.php'], 'badge' => 'Prepared INSERT' ], [ 'code' => 'Bai05', 'title' => 'Bài 05: Xóa sinh viên (DELETE)', 'desc' => 'Xóa sinh viên theo ID bằng Prepared Statement có hộp thoại xác nhận JavaScript confirm() trước khi xóa.', 'files' => ['Bai05/students.sql', 'Bai05/delete_student.php', 'Bai05/index.php'], 'badge' => 'Prepared DELETE' ], [ 'code' => 'Bai06', 'title' => 'Bài 06: Cập nhật thông tin sinh viên (UPDATE)', 'desc' => 'Tải thông tin sinh viên lên form theo ID và cập nhật họ tên, email, số điện thoại, ngày sinh bằng PDO.', 'files' => ['Bai06/students.sql', 'Bai06/edit_student.php', 'Bai06/index.php'], 'badge' => 'Prepared UPDATE' ], [ 'code' => 'Bai07', 'title' => 'Bài 07: Phân trang (Pagination) & Tìm kiếm', 'desc' => 'Phân trang danh sách sinh viên (LIMIT, OFFSET) kết hợp tìm kiếm từ khóa và đầy đủ thao tác Thêm/Sửa/Xóa.', 'files' => ['Bai07/students.sql', 'Bai07/index.php'], 'badge' => 'Pagination + CRUD' ], [ 'code' => 'Bai08', 'title' => 'Bài 08: Bổ sung cột ngày sinh (birthday)', 'desc' => 'Thực thi ALTER TABLE thêm cột birthday, cập nhật ngày sinh cho sinh viên, định dạng dd/mm/YYYY và tính tuổi.', 'files' => ['Bai08/alter_birthday.sql', 'Bai08/index.php'], 'badge' => 'ALTER TABLE & Date' ], [ 'code' => 'Bai09', 'title' => 'Bài 09: Tìm kiếm sinh viên theo tên (LIKE)', 'desc' => 'Tìm kiếm sinh viên theo tên với toán tử LIKE :keyword và PDO Prepared Statement chống SQL Injection.', 'files' => ['Bai09/students.sql', 'Bai09/search_student.php', 'Bai09/index.php'], 'badge' => 'LIKE Search' ], [ 'code' => 'Bai10', 'title' => 'Bài 10: Chuẩn hóa toàn bộ CRUD với Prepared Statement', 'desc' => 'Ứng dụng CRUD tổng hợp chuẩn hóa mọi câu lệnh SELECT, SEARCH, INSERT, UPDATE, DELETE với prepare() & execute().', 'files' => ['Bai10/students.sql', 'Bai10/index.php'], 'badge' => 'Full Prepared CRUD' ], [ 'code' => 'Bai11', 'title' => 'Bài 11: Sắp xếp danh sách sinh viên (ORDER BY)', 'desc' => 'Sắp xếp danh sách sinh viên theo cột name hoặc email (ASC/DESC) có kiểm tra whitelist tên cột an toàn.', 'files' => ['Bai11/students.sql', 'Bai11/sort_students.php', 'Bai11/index.php'], 'badge' => 'Safe Dynamic Sort' ], ]; ?>
= htmlspecialchars((string)DB_NAME) ?> (= htmlspecialchars((string)DB_HOST) ?>:= htmlspecialchars((string)DB_PORT) ?>)
Bảng students hiện có = $studentCount ?> sinh viên. Các bài tập đều tự động khởi tạo bảng nếu chưa có.
= htmlspecialchars($ex['desc']) ?>