Bài đầu tiên của loạt PHP và MySQL: vì sao PHP thường đi cùng MySQL, so sánh hai cách kết nối MySQLi và PDO, viết tệp kết nối dùng chung, xử lý lỗi kết nối và đặt bộ mã utf8mb4 để tiếng Việt hiển thị đúng.
- Hiểu vai trò của MySQL trong ứng dụng PHP
- Kết nối bằng MySQLi hướng đối tượng và PDO
- Viết tệp db_connect.php dùng chung, xử lý lỗi an toàn
- Đặt bộ mã utf8mb4 và đóng kết nối
- MySQLi
- MySQL improved: thư viện kết nối MySQL của PHP.
- PDO
- PHP Data Objects: giao diện chung cho nhiều loại CSDL.
- DSN
- Chuỗi mô tả kết nối PDO: mysql:host=...;dbname=...
- Exception
- Ngoại lệ, bắt bằng try/catch.
Khái niệm và lý thuyết
MySQL là hệ quản trị CSDL mã nguồn mở phổ biến nhất trên web, đi kèm XAMPP (dưới dạng MariaDB) và hầu hết hosting. PHP giao tiếp với MySQL qua hai thư viện:
| Tiêu chí | MySQLi | PDO |
|---|---|---|
| CSDL hỗ trợ | Chỉ MySQL/MariaDB | 12+ loại (MySQL, PostgreSQL, SQLite, SQL Server...) |
| Phong cách | Hướng đối tượng hoặc thủ tục | Hướng đối tượng |
| Prepared statement | Có, dấu ? | Có, dấu ? hoặc :ten |
| Dùng trong giáo trình | Chính | Giới thiệu, khuyên dùng cho dự án mới |
Mọi ứng dụng PHP–MySQL bắt đầu giống nhau: mở kết nối → kiểm tra lỗi → thực hiện truy vấn → xử lý kết quả → đóng kết nối. Kết nối nên viết một lần trong tệp riêng và include khi cần.
Kết nối bằng MySQLi
<?php
// db_connect.php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // lỗi thành exception (PHP 8.1+ mặc định)
$servername = "localhost";
$username = "root";
$password = ""; // XAMPP mặc định rỗng
$dbname = "qlsv";
try {
$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("utf8mb4"); // tiếng Việt
} catch (mysqli_sql_exception $e) {
error_log($e->getMessage()); // ghi log, không lộ chi tiết
exit("Không kết nối được cơ sở dữ liệu. Vui lòng thử lại sau.");
}<?php
// index.php
require_once __DIR__ . "/db_connect.php";
echo "Kết nối thành công, MySQL phiên bản " . $conn->server_info;
$conn->close(); // tùy chọn: tự đóng khi script kết thúcKết nối bằng PDO
<?php
$dsn = "mysql:host=localhost;dbname=qlsv;charset=utf8mb4";
try {
$pdo = new PDO($dsn, "root", "", [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
} catch (PDOException $e) {
error_log($e->getMessage());
exit("Lỗi kết nối CSDL");
}Tách cấu hình
<?php
// config/database.php: không commit lên GitHub
return ["host" => "localhost", "user" => "root", "pass" => "", "db" => "qlsv"];
// db_connect.php
$cfg = require __DIR__ . "/config/database.php";
$conn = new mysqli($cfg["host"], $cfg["user"], $cfg["pass"], $cfg["db"]);
$conn->set_charset("utf8mb4");Khi đổi mật khẩu hay đưa lên hosting, chỉ sửa một tệp cấu hình. Thêm config/database.php vào .gitignore, kèm tệp mẫu database.example.php.
Lỗi “Access denied for user root” nghĩa là sai mật khẩu; “Unknown database” nghĩa là chưa tạo CSDL (xem bài 2 hoặc loạt SQL, Bài 1); “Connection refused” nghĩa là MySQL trong XAMPP chưa Start.
Không in chi tiết lỗi kết nối ($e->getMessage()) ra trình duyệt trên website thật: nó có thể lộ tên máy chủ, tên người dùng CSDL.
- Tạo db_connect.php kết nối CSDL qlsv bằng MySQLi, in phiên bản MySQL.
- Viết lại bằng PDO.
- Cố ý sai mật khẩu, tên CSDL, tắt MySQL để quan sát ba loại lỗi.
- Tách cấu hình ra config/database.php.
- MySQL là CSDL phổ biến nhất cho PHP.
- MySQLi chỉ cho MySQL; PDO cho nhiều CSDL.
- Kết nối một lần trong tệp riêng, set_charset utf8mb4.
- Bắt lỗi bằng try/catch, ghi log, không lộ chi tiết.