Trong PHP, sau khi đã kết nối với cơ sở dữ liệu MySQL và tạo bảng, bước tiếp theo là chèn dữ liệu vào các bảng đó. PHP cung cấp hai cách phổ biến để thực hiện điều này: sử dụng mysqli hoặc PDO.

Bài viết này sẽ hướng dẫn bạn cách chèn dữ liệu (INSERT) vào bảng MySQL bằng cả hai phương pháp mysqliPDO, đồng thời giải thích cách xử lý lỗi và cách sử dụng Prepared Statements để bảo vệ dữ liệu khỏi SQL Injection.

1. Chèn dữ liệu vào MySQL bằng mysqli

a) Sử dụng hướng đối tượng (OOP)

php
<?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 để chèn dữ liệu
$sql = "INSERT INTO Users (username, email) VALUES ('john_doe', 'john@example.com')";

if ($conn->query($sql) === TRUE) {
    echo "Dữ liệu đã được chèn thành công!";
} else {
    echo "Lỗi khi chèn dữ liệu: " . $conn->error;
}

// Đóng kết nối
$conn->close();
?>

b) Sử dụng hướng thủ tục

php
<?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 để chèn dữ liệu
$sql = "INSERT INTO Users (username, email) VALUES ('jane_doe', 'jane@example.com')";

if (mysqli_query($conn, $sql)) {
    echo "Dữ liệu đã được chèn thành công!";
} else {
    echo "Lỗi khi chèn dữ liệu: " . mysqli_error($conn);
}

// Đóng kết nối
mysqli_close($conn);
?>

Giải thích:

  • Câu lệnh SQL INSERT INTO được sử dụng để thêm dữ liệu vào bảng Users.
  • Nếu quá trình chèn dữ liệu thành công, PHP sẽ in ra thông báo "Dữ liệu đã được chèn thành công!". Nếu không, thông báo lỗi sẽ được hiển thị.

2. Chèn dữ liệu vào MySQL bằng PDO

Sử dụng PDO để chèn dữ liệu vào MySQL rất dễ dàng và mang lại nhiều lợi ích như khả năng di chuyển mã qua lại giữa các hệ quản trị cơ sở dữ liệu khác nhau và xử lý lỗi linh hoạt.

php
<?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);
    // Cài đặt chế độ lỗi PDO thành Exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Câu lệnh SQL để chèn dữ liệu
    $sql = "INSERT INTO Users (username, email) VALUES ('alice', 'alice@example.com')";

    // Thực hiện câu lệnh
    $conn->exec($sql);
    echo "Dữ liệu đã được chèn thành công!";
} catch(PDOException $e) {
    echo "Lỗi khi chèn dữ liệu: " . $e->getMessage();
}

// Đóng kết nối
$conn = null;
?>

Giải thích:

  • PDO::exec() được sử dụng để thực hiện các truy vấn SQL không trả về kết quả (như INSERT, UPDATE, DELETE).
  • Mọi lỗi sẽ được xử lý thông qua khối try-catch.

3. Bảo mật SQL với Prepared Statements

Để ngăn chặn SQL Injection, bạn nên sử dụng Prepared Statements. Điều này giúp tách biệt phần truy vấn SQL và dữ liệu được chèn vào, đảm bảo an toàn cho cơ sở dữ liệu.

a) Prepared Statements với mysqli

php
<?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à liên kết tham số
$stmt = $conn->prepare("INSERT INTO Users (username, email) VALUES (?, ?)");
$stmt->bind_param("ss", $username, $email);

// Gán giá trị cho các tham số và thực thi câu lệnh
$username = "charlie";
$email = "charlie@example.com";
$stmt->execute();

echo "Dữ liệu đã được chèn thành công!";

// Đóng kết nối
$stmt->close();
$conn->close();
?>

b) Prepared Statements với PDO

php
<?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);
    // Cài đặt chế độ lỗi PDO thành Exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Chuẩn bị câu lệnh SQL
    $stmt = $conn->prepare("INSERT INTO Users (username, email) VALUES (:username, :email)");

    // Gán giá trị cho các tham số
    $stmt->bindParam(':username', $username);
    $stmt->bindParam(':email', $email);

    // Gán giá trị và thực thi câu lệnh
    $username = "dave";
    $email = "dave@example.com";
    $stmt->execute();

    echo "Dữ liệu đã được chèn thành công!";
} catch(PDOException $e) {
    echo "Lỗi khi chèn dữ liệu: " . $e->getMessage();
}

// Đóng kết nối
$conn = null;
?>

Giải thích:

  • Prepared Statements giúp 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à dữ liệu đầu vào.
  • Tham số được truyền vào câu lệnh SQL dưới dạng các biến (? trong mysqli hoặc :param trong PDO).
  • Trong cả hai trường hợp, bạn cần liên kết tham số với các giá trị trước khi thực thi câu lệnh.

4. Xử lý lỗi khi chèn dữ liệu

Khi làm việc với cơ sở dữ liệu, bạn cần xử lý các lỗi có thể xảy ra trong quá trình chèn dữ liệu, chẳng hạn như:

  • Kết nối thất bại: Khi không thể kết nối với cơ sở dữ liệu.
  • Lỗi cú pháp SQL: Khi câu lệnh SQL có lỗi cú pháp.
  • Lỗi khi vi phạm ràng buộc: Ví dụ, nếu bảng yêu cầu trường email phải là duy nhất, việc chèn một email trùng lặp sẽ dẫn đến lỗi.

Ví dụ xử lý lỗi:

Với mysqli:

php
if ($conn->query($sql) === TRUE) {
    echo "Dữ liệu đã được chèn thành công!";
} else {
    echo "Lỗi khi chèn dữ liệu: " . $conn->error;
}

Với PDO:

php
try {
    $conn->exec($sql);
} catch(PDOException $e) {
    echo "Lỗi khi chèn dữ liệu: " . $e->getMessage();
}

5. Đóng kết nối

Sau khi hoàn thành việc chèn dữ liệu, đừng quên đóng kết nối với cơ sở dữ liệu để giải phóng tài nguyên.

  • mysqli:
php
$conn->close();
  • PDO:
php
$conn = null;

Kết luận

Việc chèn dữ liệu vào MySQL thông qua PHP có thể được thực hiện dễ dàng với cả mysqliPDO. Bằng cách sử dụng Prepared Statements, bạn có thể bảo vệ ứng dụng của mình khỏi các cuộc tấn công SQL Injection và đảm bảo rằng dữ liệu được xử lý an toàn.

  • mysqli: Phù hợp nếu bạn chỉ làm việc với MySQL và cần một API dễ sử dụng.
  • PDO: Là lựa chọn linh hoạt nếu bạn làm việc với nhiều hệ quản trị cơ sở dữ liệu khác nhau và muốn có khả năng dễ dàng chuyển đổi giữa chúng.

Hãy thực hành các phương pháp trên và sử dụng Prepared Statements để bảo vệ ứng dụng của bạn!