Laravel là một framework PHP mạnh mẽ, nổi bật với cách thức làm việc dễ dàng và linh hoạt, đặc biệt là trong việc tương tác với cơ sở dữ liệu. Tuy nhiên, trong một số trường hợp, chúng ta cần thực thi các truy vấn “raw” (truy vấn thô) để xử lý những yêu cầu đặc biệt. Bài viết này sẽ hướng dẫn bạn cách chạy raw queries trong Laravel, đồng thời đảm bảo an toàn khi thực hiện với các phương pháp bảo mật hiệu quả.
1. Raw Queries Là Gì?
Raw queries là những câu lệnh SQL được viết trực tiếp trong mã nguồn của bạn, không thông qua Eloquent hoặc Query Builder của Laravel. Việc này có thể cần thiết khi bạn muốn tối ưu hóa hiệu suất hoặc thực hiện các thao tác mà Eloquent không hỗ trợ một cách trực tiếp.
2. Cách Thực Thi Raw Queries
Để chạy raw queries, Hoclaravel.vn giới thiệu phương thức DB::select()
. Ở đây, chúng ta có thể viết truy vấn SQL của mình như sau:
$post = \DB::select("SELECT * FROM posts WHERE id = ?", [1]);
Truy vấn này sẽ lấy các thông tin về một bài viết có id
bằng 1. Bằng cách này, chúng ta có thể chạy các câu truy vấn tùy ý theo nhu cầu của ứng dụng.
3. Bảo Mật: Ngăn Chặn SQL Injection
Khi làm việc với raw queries, bảo mật là một yếu tố cực kỳ quan trọng. Một trong những rủi ro lớn nhất mà bạn sẽ phải đối mặt là SQL Injection, một kỹ thuật tấn công mà kẻ xấu có thể lợi dụng để thao túng cơ sở dữ liệu của bạn.
Vấn Đề SQL Injection
Ví dụ dưới đây có thể gây ra lỗ hổng bảo mật:
$author = 'Channaveer';
$publishedDate = '2020-02-01';
$post = \DB::select("
SELECT id, title, body, author, published_on
FROM posts
WHERE published_on >= '$publishedDate' AND author = '$author'
");
Trong đoạn mã trên, việc sử dụng biến trực tiếp trong câu truy vấn đã làm tăng nguy cơ bị tấn công.
Giải Pháp: Sử Dụng Positional Bindings và Named Bindings
Để bảo vệ ứng dụng của bạn khỏi SQL Injection, bạn cần sử dụng các phương pháp gán biến an toàn như Positional Bindings và Named Bindings.
3.2.1. Positional Bindings
Áo dụng “?”:
$post = \DB::select("
SELECT id, title, body, author, published_on
FROM posts
WHERE published_on >= ? AND author = ?
", [$publishedDate, $author]);
Trong trường hợp này, giá trị của $publishedDate
và $author
sẽ được gán vào vị trí tương ứng trong câu truy vấn mà không cần phải chèn trực tiếp vào.
3.2.2. Named Bindings
Sử dụng “:”:
$post = \DB::select("
SELECT id, title, body, author, published_on
FROM posts
WHERE published_on >= :publishedDate AND author = :author
", [
'publishedDate' => $publishedDate,
'author' => $author
]);
Với named bindings, bạn có thể giảm bớt sự phụ thuộc vào thứ tự các tham số, giúp mã nguồn dễ đọc và bảo trì hơn.
Thực Hiện Các Thao Tác CRUD Với Raw Queries
Laravel cung cấp cho chúng ta những phương thức riêng để thực hiện các thao tác CRUD (Create, Read, Update, Delete) thông qua raw queries. Dưới đây là cách thực hiện các thao tác này:
Fetch Details – DB::select()
Để lấy thông tin từ cơ sở dữ liệu:
$post = \DB::select("
SELECT id, title, body, author, published_on
FROM posts
WHERE published_on >= :publishedDate AND author = :author
", [
'publishedDate' => $publishedDate,
'author' => $author
]);
Insert Details – DB::insert()
Để thêm dữ liệu vào bảng:
\DB::insert("
INSERT INTO posts (title, body, author, published_on)
VALUES (:title, :body, :author, :published_on)
", [
'title' => 'Tiêu đề bài viết',
'body' => 'Nội dung bài viết',
'author' => $authorId,
'published_on' => now()
]);
Update Details – DB::update()
Thực hiện cập nhật thông tin:
\DB::update("
UPDATE posts
SET title = :title, body = :body, published_on = :published_on
WHERE id = :id
", [
'id' => $postId,
'title' => 'Tiêu đề mới',
'body' => 'Nội dung đã cập nhật',
'published_on' => now()
]);
Delete Details – DB::delete()
Để xóa bản ghi:
\DB::delete("
DELETE FROM posts WHERE id = :id
", [
'id' => $postId
]);
Generic Statements – DB::statement()
Khi cần thực hiện các câu lệnh không trả về kết quả:
\DB::statement("DROP TABLE posts");
Kết Luận
Việc chạy raw queries trong Laravel không chỉ hữu ích mà còn cần thiết trong nhiều trường hợp. Tuy nhiên, bạn cần lưu ý đến các vấn đề về bảo mật, đặc biệt là SQL Injection. Hãy sử dụng các phương pháp binding an toàn để đảm bảo tính toàn vẹn cho cơ sở dữ liệu của bạn.