Trong lập trình PHP, việc truy vấn dữ liệu từ cơ sở dữ liệu MySQL là một nhiệm vụ quan trọng. Bạn có thể thực hiện các truy vấn SELECT để lấy dữ liệu từ bảng và hiển thị ra trang web. PHP cung cấp hai phương pháp phổ biến để kết nối và thực hiện truy vấn dữ liệu MySQL: mysqli và PDO.
Trong bài viết này, chúng ta sẽ tìm hiểu cách sử dụng cả mysqli và PDO để thực hiện truy vấn SELECT và lấy dữ liệu từ cơ sở dữ liệu MySQL.
1. Sử dụng mysqli để truy vấn dữ liệu
a) mysqli - Hướng đối tượng (OOP)
Dưới đây là một ví dụ về cách sử dụng mysqli để truy vấn dữ liệu từ cơ sở dữ liệu theo mô hình hướng đối tượng.
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
// Tạo kết nối
$conn = new mysqli($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if ($conn->connect_error) {
die("Kết nối thất bại: " . $conn->connect_error);
}
// Câu lệnh SQL để lấy dữ liệu
$sql = "SELECT id, username, email FROM Users";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// Lặp qua các bản ghi kết quả
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"]. " - Username: " . $row["username"]. " - Email: " . $row["email"]. "<br>";
}
} else {
echo "Không có dữ liệu.";
}
// Đóng kết nối
$conn->close();
?>Giải thích:
$conn->query($sql): Thực hiện câu lệnh SQL và trả về đối tượng kết quả.$result->num_rows: Kiểm tra xem có bao nhiêu bản ghi được trả về từ truy vấn.fetch_assoc(): Trả về từng bản ghi dưới dạng mảng kết hợp (associative array).
b) mysqli - Hướng thủ tục
Cách tiếp cận hướng thủ tục tương tự như hướng đối tượng, nhưng sử dụng các hàm thủ tục như mysqli_query() và mysqli_fetch_assoc().
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
// Tạo kết nối
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if (!$conn) {
die("Kết nối thất bại: " . mysqli_connect_error());
}
// Câu lệnh SQL để lấy dữ liệu
$sql = "SELECT id, username, email FROM Users";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// Lặp qua các bản ghi kết quả
while ($row = mysqli_fetch_assoc($result)) {
echo "ID: " . $row["id"]. " - Username: " . $row["username"]. " - Email: " . $row["email"]. "<br>";
}
} else {
echo "Không có dữ liệu.";
}
// Đóng kết nối
mysqli_close($conn);
?>Giải thích:
mysqli_query($conn, $sql): Thực hiện truy vấn SQL.mysqli_num_rows($result): Kiểm tra số lượng bản ghi được trả về.mysqli_fetch_assoc($result): Trả về bản ghi dưới dạng mảng kết hợp.
2. Sử dụng PDO để truy vấn dữ liệu
PDO là một API mạnh mẽ và linh hoạt hỗ trợ nhiều hệ quản trị cơ sở dữ liệu khác nhau, bao gồm MySQL.
Ví dụ sử dụng PDO:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
try {
// Tạo kết nối PDO
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Câu lệnh SQL để lấy dữ liệu
$sql = "SELECT id, username, email FROM Users";
$stmt = $conn->prepare($sql);
$stmt->execute();
// Đặt chế độ trả về là mảng kết hợp
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Kiểm tra và hiển thị dữ liệu
if ($stmt->rowCount() > 0) {
foreach ($result as $row) {
echo "ID: " . $row['id'] . " - Username: " . $row['username'] . " - Email: " . $row['email'] . "<br>";
}
} else {
echo "Không có dữ liệu.";
}
} catch(PDOException $e) {
echo "Lỗi: " . $e->getMessage();
}
// Đóng kết nối
$conn = null;
?>Giải thích:
prepare(): Chuẩn bị câu lệnh SQL để thực thi.execute(): Thực hiện câu lệnh đã chuẩn bị.fetchAll(PDO::FETCH_ASSOC): Lấy tất cả các bản ghi và trả về dưới dạng mảng kết hợp (associative array).rowCount(): Kiểm tra số lượng bản ghi được trả về từ câu lệnh SQL.
3. Sử dụng Prepared Statements cho truy vấn SELECT
Prepared Statements giúp bảo vệ ứng dụng của bạn khỏi các cuộc tấn công SQL Injection khi làm việc với dữ liệu người dùng đầu vào. Prepared Statements đảm bảo rằng các tham số đầu vào được xử lý an toàn trước khi chèn vào câu lệnh SQL.
a) Prepared Statements với mysqli
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
// Tạo kết nối
$conn = new mysqli($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if ($conn->connect_error) {
die("Kết nối thất bại: " . $conn->connect_error);
}
// Chuẩn bị câu lệnh SQL với tham số
$stmt = $conn->prepare("SELECT id, username, email FROM Users WHERE username = ?");
$stmt->bind_param("s", $username);
// Gán giá trị cho biến và thực thi câu lệnh
$username = "john_doe";
$stmt->execute();
// Liên kết kết quả với các biến
$stmt->bind_result($id, $username, $email);
// Lặp qua các kết quả
while ($stmt->fetch()) {
echo "ID: $id - Username: $username - Email: $email<br>";
}
// Đóng câu lệnh và kết nối
$stmt->close();
$conn->close();
?>b) Prepared Statements với PDO
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
try {
// Tạo kết nối PDO
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Chuẩn bị câu lệnh SQL với tham số
$stmt = $conn->prepare("SELECT id, username, email FROM Users WHERE username = :username");
$stmt->bindParam(':username', $username);
// Gán giá trị và thực thi câu lệnh
$username = "john_doe";
$stmt->execute();
// Lấy kết quả trả về dưới dạng mảng kết hợp
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Hiển thị kết quả
if ($stmt->rowCount() > 0) {
foreach ($result as $row) {
echo "ID: " . $row['id'] . " - Username: " . $row['username'] . " - Email: " . $row['email'] . "<br>";
}
} else {
echo "Không có dữ liệu.";
}
} catch(PDOException $e) {
echo "Lỗi: " . $e->getMessage();
}
// Đóng kết nối
$conn = null;
?>Giải thích:
- Prepared Statements bảo vệ ứng dụng khỏi các cuộc tấn công SQL Injection bằng cách tách biệt câu lệnh SQL và các giá trị dữ liệu.
- Các tham số trong câu lệnh SQL (
?trongmysqli,:paramtrong PDO) được liên kết với các biến để đảm bảo rằng dữ liệu đầu vào được thoát đúng cách.
4. Xử lý lỗi khi truy vấn dữ liệu
Trong quá trình truy vấn dữ liệu, có thể xảy ra các lỗi như:
- Lỗi kết nối cơ sở dữ liệu.
- Lỗi cú pháp SQL.
- Lỗi khi dữ liệu không tồn tại.
Bạn có thể xử lý các lỗi này bằng cách sử dụng khối try-catch trong PDO hoặc kiểm tra lỗi với $conn->error trong mysqli.
Ví dụ xử lý lỗi với mysqli:
if ($conn->query($sql) === FALSE) {
echo "Lỗi khi thực hiện truy vấn: " . $conn->error;
}Ví dụ xử lý lỗi với PDO:
try {
$stmt->execute();
} catch(PDOException $e) {
echo "Lỗi: " . $e->getMessage();
}5. Kết luận
Việc lấy dữ liệu từ cơ sở dữ liệu MySQL bằng PHP là một tác vụ phổ biến trong các ứng dụng web. Cả hai phương pháp mysqli và PDO đều cung cấp các cách đơn giản và linh hoạt để thực hiện truy vấn SELECT. Sử dụng Prepared Statements giúp bảo vệ dữ liệu của bạn và ngăn chặn các cuộc tấn công SQL Injection.
mysqli: Phù hợp cho các dự án chỉ sử dụng MySQL và có thể làm việc theo cả hướng thủ tục và hướng đối tượng.- PDO: Linh hoạt hơn, hỗ trợ nhiều hệ quản trị cơ sở dữ liệu khác nhau và chỉ làm việc theo hướng đối tượng.
Chọn phương pháp phù hợp với dự án của bạn và tiếp tục cải thiện kỹ năng lập trình PHP với MySQL!









