Cách Để Chạy Raw Queries Trong Laravel

Cách Để Chạy Raw Queries Trong Laravel
Chạy raw queries có khó không? Thực ra quá trình này không khó khi bạn thường xuyên thực hiện nó trong các ứng dụng hoặc các dự án.

Một số dự án yêu cầu các bạn cần chạy raw queries trong Laravel. Chạy raw queries có khó không? Thực ra không khó khi bạn biết cách thực hiện. Trong bài chia sẻ này, bạn sẽ biết cách làm và còn ngăn được SQL injection với raw queries. Laravel có cơ chế tốt để chúng ta thực hiện phần cơ sở dữ liệu trên ứng dụng một cách trọn vẹn. Đó là Eloquent và Query Builder. Trong nhiều trường hợp, các bạn cần chạy Query đơn thuần dưới dạng Raw Query. 

 

RAW Queries Syntax 

 

Để khởi chạy raw queries, các bạn nên sử dụng phương thức DB::select() với cú pháp dưới đây:

 

\DB::select("

    /** Your Query */

");

Problem (SQL Injection)

 

Các bạn nên chạy các raw queries như dưới đây. Ví dụ các bạn muốn lấy các posts mà có author và published_on mà lớ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

");

 

Vấn đề bảo mật đóng vai trò quan trọng trong các ứng dụng của bạn. Thậm chí bạn chạy bất kỳ ứng dụng cho mục đích nội bộ thì bạn cũng nên lưu ý đến chuyện bảo mật. Vì có thể phát sinh yêu cầu publish ở đâu đó để bạn truy cập từ xa. Bạn quan sát thấy published_on >= $publishedDate và author = $author đã harcoded hay chưa? Thông thường, đây chính là lỗ hổng phổ biến và đáng lưu tâm vì nó dễ bị SQL Injection và khai thác cơ sở dữ liệu ngầm của bạn.

 

Giải pháp (Positional Bindings & Named Bindings)

 

Positional Bindings ( ? ) 

 

Ở vị trí binding, các bạn sẽ sử dụng ? để tạo chỗ cho các giá trị và sau đó chuyển các giá trị đó vào trong tham số thứ nhì thành mảng thông thường. Đừng quên các bạn phải tuân thủ cùng một chuỗi các vị trí. Lưu ý 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ứ nhì và kế tiếp sẽ 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, các bạn nên sử dụng : với tên là placeholder (ví dụ :publishedOn). Tại đây, các bạn không nhất thiết phải theo thứ tự 1,2,3…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 ]

);

Khi thực hiện như vậy, ứng dụng của các bạn sẽ tránh được trường hợp SQL injection.

 

Fun Part 

 

Các bạn có thể chạy các phép toán CRUD trong hàm \DB:select(). Tuy nhiên, các bạn không nên thực hiện như vậy. Vì Laravel đã có DB:select DB::insert DB::update DB::delete DB::statement. 

 

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

 

Fetch Details - DB::select()

 

Để lấy bất cứ chi tiết nào từ cơ sở dữ liệu của bạn, bạn nên sử dụng phương thức đó. Nó giúp bạn thấy hiện trạng trước đó như thế nào và bạn cũng có thể thấy được mảng kết quả hiện tại. 

 

$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()

 

Để thêm vào bảng cơ sở dự liệu, bạn nên dùng phương thức này. Vì nó có thể nhận query trong tham số đầu tiên và các giá trị trong tham số thứ 2. 

 

$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 bản ghi đã tồn tại trước đó, các bạn nên cập nhật trả về số lượng row 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()

 

Để xóa bất cứ bản ghi nào từ cơ sở dữ liệu của bạn, thì bạn sẽ xóa và trả về số row bị ảnh hưởng. 

 

$post = \DB::delete("

    DELETE

    FROM 

        posts

    WHERE

        id = :id

    ", [ 

        "id"      => $id

    ]

);

 

Generic Statements - DB::statement()

 

Trong quá trình thực hiện dự án, các bạn sẽ đối mặt với tình trạng nhiều queries không thể trả về kết quả. Do đó, bạn nên chạy các câu lệnh chung mà sẽ sử dụng phương thức này. 

 

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

 

Nguy hiểm lớn nhất mà các bạn phải đối mặt khi thực hiện raw queries là nó không tự động xử lý các tham số truyền vào. Vì vậy, nếu bạn truyền vào bất kỳ tham số nào với câu truy vấn, thì bạn nên:

 

  • Kiểm tra dòng lệnh
  • Validate giá trị
  • Định dạng chúng cẩn thận

Hồ Hữu Hiền

Mình là developer nên đôi khi viết bài không hay lắm mong các bạn thông cảm. Nếu muốn biết thêm thông tin về mình thì vui lòng vào website này để biết. https://huuhienqt.dev/

Bình luận (0)