Làm sao để chạy raw queries an toàn trong Laravel

13.08.2020

5.0/5 (1 Reviews)

Làm sao để chạy raw queries an toàn trong Laravel, hãy cùng chúng tôi xem qua 1 số cách bạn nhé.

    Đôi khi, có thể có một số yêu cầu cần phải chạy các raw queries trong Laravel. Trong bài viết này, bạn sẽ tìm hiểu cách chạy các raw queries trong Laravel và cách ngăn chặn SQL injection với nó.

    Prerequisites

    • Làm việc ứng dụng Laravel và nhiệt tình học hỏi 
    • Ở đây tôi sẽ giới thiệu các ví dụ đơn giản phải cung cấp cho bạn thông tin chi tiết về cách chạy các truy vấn phức tạp

    Running RAW Queries Syntax

    Để chạy raw queries bạn sử dụng phương thức DB::select() với cú pháp như sau:

    \DB::select("
        /** Your Query */
    ");
    

    Problem (SQL Injection)

    Bạn phải chạy các raw queries như sau.

    Ví dụ: Tôi muốn lấy các posts mà có authorpublished_onlớn hơn một số ngày

    $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
    ");
    

    Không có gì sai trong query trên. Mọi thứ đều hoạt động tốt.

    Còn vấn đề bảo mật thì sao? Bảo mật đóng một vai trò quan trọng trong ứng dụng của bạn, ngay cả khi bạn chạy ứng dụng cho mục đích nội bộ, có thể phát sinh yêu cầu publish nó ở đâu đó để có thể truy cập từ xa.

    Quan sát published_on >= $publishedDateauthor = $author được hardcoded, đây là lỗ hổng thực sự nơi dễ bị SQL Injection và khai thác cơ sở dữ liệu của bạn.

    Solution (Positional Bindings & Named Bindings)

    Positional Bindings ( ? )

    Tại vị trí binding chúng ta sẽ sử dụng ? làm chỗ dành cho các giá trị và sau đó chuyển các giá trị này trong tham số thứ 2 thành mảng thông thường và phải tuân theo cùng một chuỗi các vị trí.

    LƯU Ý: Điều tôi muốn nói là với cùng một chuỗi các vị trí trong ví dụ, published_on xuất hiện đầu tiên trong query, do đó, $publishedDate xuất hiện trước trong mảng tham số thứ 2 và sau đó là author & $author tương ứng.

    $author         = 'Channaveer';
    $publishedDate  = '2020-02-01';
    
    $post = \DB::select("
        SELECT 
            id, title, body, author, published_on
        FROM
            posts
        WHERE
            published_on >= ?
                and
            author = ?
        ",
        [ $publishedDate, $author ]
    );
    

     

    Named Binding ( : )

    Trong các binding được đặt tên, chúng ta sử dụng : với name là placeholder. Ví dụ :publishedOn. Ở đây không cần phải theo thứ tự thứ nhất và thứ hai như trước đó

    $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
        ", 
        [ ":publishedDate" => $publishedDate, ":author" => $author ]
    );
    

    Điều nay giúp bạn tránh khỏi các SQL Injection.

     

    FUN PART

    Bạn có thể chạy các phép toán CRUD của mình trong hàm \DB:select(). Nhưng không nên làm như vậy. Vì Laravel đã cho DB:selectDB::insertDB::updateDB::deleteDB::statement cho nó.

     

    CRUD OPERATIONS ( DB::select(), DB::update(), DB::insert(), DB::delete(), DB::statement() )

    Tip: Tôi thường thích Bindings được đặt tên với :name vì nó sẽ rõ ràng hơn và có thể maintainable trong tương lai mà không gặp nhiều rắc rối

     

    Fetch Details - DB::select()

    Để lấy bất kỳ details nào từ cơ sở dữ liệu, bạn sử dụng phương thức này như bạn đã thấy trước đó. Điều này trả về mảng kết quả.

    $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
        ", 
        [ ":publishedDate" => $publishedDate, ":author" => $author ]
    );
    

     

    Insert Details - DB::insert()

    Để insert vào bảng cơ sở dữ liệu của bạn, bạn sử dụng phương thức này.Nó nhận query trong tham số đầu tiên và các giá trị trong tham số thứ hai:

    $post = \DB::insert("
        INSERT INTO 
            posts
                (title, body, author, published_on)
        VALUES
            (:title, :body, :author, :published_on)
        ", [ 
            ":title"        => request('title'),
            ":body"         => request('body') , 
            ":author"       => session()->get('user_details')->id,
            ":published_on" => request('published_on')
        ]
    );
    

     

    Update Details - DB::update()

    Để cập nhật các record đã tồn tại chúng ta sử dụng như sau. update trả về số lượng rows bị ảnh hưởng.

    $post = \DB::update("
        UPDATE 
            posts
        SET
            title      = :title,
            body      = :body,
            published_on  = :published_on
        WHERE
            id = :id
        ", [ 
            "id"      => $id
            ":title"    => request('title'),
            ":body"     => request('body') , 
            ":published_on" => request('published_on')
        ]
    );
    

     

    Delete Details - DB::delete()

    Để delete bất kỳ record nào từ cơ sở dữ liệu sử dụng theo cách sau. delete sẽ trả về số rows bị ảnh hưởng.

    $post = \DB::delete("
        DELETE
        FROM 
            posts
        WHERE
            id = :id
        ", [ 
            "id"      => $id
        ]
    );
    

     

    Generic Statements - DB::statement()

    Nhiều queries không trả về kết quả, vì vậy chạy các câu lệnh chung sẽ sử dụng phương thức này.

    \DB::statement("DROP TABLE posts");
    

     

    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    LPStack Server: Giải pháp thay thế XAMPP và MAMP năm 2026

    10.03.2026

    Bạn đã chán ngấy XAMPP hay MAMP chậm chạp? Khám phá LPStack Server – Môi trường Local Development siêu nhẹ của người Việt với Auto Vhost, Public Tunnel, chuyển đổi PHP 1-click và quản lý Database Native chuyên nghiệp

    thumbnail

    Hướng Dẫn Tạo Trò Chơi Cờ Caro Nâng Cao bằng HTML

    19.03.2025

    Chào các bạn! Trong bài viết này, chúng ta sẽ cùng nhau xây dựng một trò chơi Cờ Caro đơn giản nhưng có nhiều tính năng thú vị như giới hạn nước đi, pháo hoa khi chiến thắng, chọn chế độ chơi và đếm thời gian.

    thumbnail

    Grok AI: Giới thiệu chi tiết về chatbot của Elon Musk

    04.03.2025

    Grok là một chatbot AI tiên tiến, được phát triển bởi xAI, công ty do Elon Musk sáng lập. Ra mắt lần đầu vào tháng 11/2023, Grok được thiết kế để cạnh tranh với các mô hình AI nổi tiếng như ChatGPT

    thumbnail

    Hướng dẫn tạo Livechat trả lời bằng AI Grok của X

    04.03.2025

    Hướng dẫn kỹ thuật tạo Livechat AI bằng HTML, CSS, JavaScript và PHP Dưới đây là hướng dẫn từng bước để xây dựng một ứng dụng livechat AI đơn giản. Chúng ta sẽ có giao diện frontend (HTML, CSS, JS) và backend (PHP) xử lý tin nhắn.

    thumbnail

    Temu Affiliate là gì? Cách kiếm tiền với Temu mới nhất 2024

    23.10.2024

    Temu Affiliate là một chương trình tiếp thị liên kết mới mẻ được đưa ra bởi sàn thương mại điện tử Temu. Tham gia ⭐️ Chương trình tiếp thị liên kết Temu⭐️! Lên đến ????₫2.500.000.000 mỗi tháng