Tìm hiểu HTTP Request trong Laravel

Laravel

Trong bài viết này, tôi xin giới thiệu về Request trong Laravel – Đây là thư viện được sử dụng nhiều nhất trong các dự án ứng dụng phát triển trên nền tảng Website.

Truy cập vào Request

Để lấy đối tượng hiện tại của HTTP request thông qua dependency injection, bạn phải type-hint vào class Illuminate\Http\Request trong phương thức controller. Các request đến sẽ được tự động injected bởi service container:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $name = $request->input('name');
    }
}

Dependency Injection & Route Parameters

Nếu phương thức controller của bạn cũng cần lấy input từ tham số route thì bạn phải liệt kê danh sách tham số route vào sau các dependencies. Ví dụ, nếu route của bạn định nghĩa như sau:

Route::put('user/{id}', 'UserController@update');

Bạn vẫn phải type-hint Illuminate\Http\Request và truy cập vào tham số route id bằng cách định nghĩa phương thức trong controller như sau:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function update(Request $request, $id)
    {
        //
    }
}

Truy cập vào Request qua Route Closures

Bạn cũng có thể type-hint class Illuminate\Http\Request trong route Closure. Service sẽ tự động inject các request Closure khi nó sẽ được thực thi:

use Illuminate\Http\Request;

Route::get('/', function (Request $request) {
    //
});

Đường dẫn Request & Phương thức

Đối tượng Illuminate\Http\Request cung cập một số phương thức để kiểm tra HTTP request cho ứng dụng và kế thừa class Symfony\Component\HttpFoundation\Request . Chúng ta sẽ thảo luận một số phương thức quan trọng dưới đây.

Nhận đường dẫn Request

Phương thức path trả về thông tin đường dẫn của request. Vì vậy, Nếu request gửi đến là http://domain.com/foo/bar, phương thức path sẽ trả về foo/bar:

uri = $request->path();

hương thức is sẽ cho phép bạn xác nhận những request gửi đến có đường dẫn khới với pattern hay không. Bạn có thể sử dụng ký tự * khi sử dụng phương thức này:

if ($request->is('admin/*')) {
    //
}

Nhận Request URL

Để nhận đường dẫn đầy đủ URL từ request gửi đến bạn có thể sử dụng phương thức url or fullUrl. Phương thức url sẽ trả về URL không có string query, trong khi phương thức fullUrl bao gồm cả string query:

// Without Query String...
$url = $request->url();

// With Query String...
$url = $request->fullUrl();

Nhận phương thức Request

Phương thức method sẽ trả về phương thức HTTP tương ứng với request. Bạn có thể sử dụng phương thức isMethod để xác thực phương thức HTTP khớp với string:

$method = $request->method();

if ($request->isMethod('post')) {
    //
}

PSR-7 Requests

Tiêu chuẩn của PSR-7 standard quy định interfaces cho HTTP messages, bao gồm cả requests và responses. Nếu bạn muốn lấy một đối tượng chuẩn của PSR-7 request thay vì một request Laravel, Đầu tiên bạn cần cài đặt một vài thư viện. Laravel sử dụng component Symfony HTTP Message Bridgeđể chuyển đổi requests và responses của Laravel thành PSR-7:

composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros

Khi bạn đã cài thư viện trên, bạn có thể lấy được PSR-7 request bằng cách type-hinting request interface trên route Closure hoặc phương thức controller:

use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
    //
});

Trường hợp nếu bạn trả về PSR-7 response từ route hoặc controller, nó sẽ tự động chuyển thành response Laravel và được hiển thị bởi framework.

Lấy Input

Lấy tất cả dữ liệu Input

Bạn có thể lấy tất cả dữ liệu input như một array bằng cách sử dụng phương thức all:

$input = $request->all();

Lấy giá trị một Input

Sử dụng một vài phương thức cơ bản, bạn có thể truy cập tất cả các input từ người dùng qua Illuminate\Http\Request mà bạn không cần quan tâm tới các method HTTP được sử dụng cho request. Bất kể nó là phương thức HTTP nào, phương thức input sử dụng có thể lấy được input từ người dùng:

$name = $request->input('name');

Bạn cũng có thể truyền giá trị của tham số như là một đối số thứ hai trong phương thức input. Giá trị sẽ được trả về nếu giá trị input không có trong request:

$name = $request->input('name', 'Sally');

Khi bạn làm việc với form chứa mảng input, sử dụng dấm “chấm” để truy cập giá trị của mảng:

$name = $request->input('products.0.name');
$names = $request->input('products.*.name');

Lấy Input qua thuộc tính động

Bạn có thể lấy input của người dùng bằng cách sử dụng thuộc tính động trong Illuminate\Http\Request. Ví dụ, Nếu form ứng dụng của bạn có chứa trường name, bạn có thể truy lấy giá trị bằng cách:

$name = $request->name;

Khi sử dụng thuộc tính động, đầu tiên Laravel sẽ tìm giá trị tham số trong request payload. Nếu nó không tìm thấy, Laravel laravel sẽ tìm trong tham số route.

Lấy giá trị JSON Input

Khi bạn gửi JSON requests đến ứng dụng, bạn có thể lấy dữ liệu JSON qua phương thức input miễn là Content-Type header của request là application/json. Bạn cũng có thể dùng cú pháp “dấu chấm” để lấy giá trị mảng JSON:

$name = $request->input('user.name');

Lấy một phần dữ liệu Input

Nếu bạn cần một tập con dữ liệu input, bạn có thể sử dụng phương thức only và except. Cả hai phương thức đều nhận một array hoặc một danh sách các đối số:

input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');

Kiểm tra giá trị Input Value tồn tại

Bạn có thể dùng phương thức has để kiểm tra giá trị input tồn tại trong request. Phương thức hastrả về true nếu giá trị tồn tại và không phải chuỗi rỗng:

if ($request->has('name')) {
    //
}

Input cũ

Laravel cho phép bạn giữ giá trị input từ lần request cữ tới request tiếp theo. Nó thật sự hữu dụng khi bạn muốn thiết lập lại form sau khi có validate lỗi. Tuy nhiên, nếu bạn sử dụng validation features của Laravel, thì bạn không phải làm việc này, vì Laravel’s built-in validation đã tự động làm việc đó cho bạn rồi.

Flashing Input tới Session

Phương thức flashtrong class Illuminate\Http\Request sẽ flash hiện tại input vào trong session vì vậy bạn có thể sử dụng trong request tiếp theo của người dùng tới ứng dụng:

$request->flash();

Bạn cũng có thể sử dụng phương thức flashOnly và flashExceptđể flash một tập con dữ liệu request vào trong session. Nhưng phương thức này rất hữu ích cho việc dữ những thông tin nhạy cảm như mật khẩu ra session:

$request->flashOnly(['username', 'email']);
$request->flashExcept('password');

Flashing Input rồi chuyển trang

Thỉnh thoảng bạn muốn flash input vào session và chuyển trang về trang trước đó, bạn có thể dễ dàng tạo móc nối vào trong một chuyển trang với phương thức withInput:

return redirect('form')->withInput();
return redirect('form')->withInput(
    $request->except('password')
);

Lấy input cũ

Để lấy flashed input từ request trước, sử dụng phương thứcold của Request. Phương thức old sẽ lấy dữ liệu flashed input data trước ra khỏi session:

$username = $request->old('username');

Laravel còn cung cấp một helper global old. Nếu bạn muốn hiển input cũ trong Blade template, nó thật tiện khi sử dụng helper old. Nếu không có input cũ của trường, null sẽ được trả về:

<input type="text" name="username" value="{{ old('username') }}">

Cookies

Lấy Cookies From Requests

Tất cả cookies dược tạo bởi Laravel framework đều được mã hóa và ký một mã xác thực, nghĩa là chúng có thể bị coi là không hợp lệ nếu nó bị thay đổi phía dưới client. Để lấy một giá trị cookie từ request, sử dụng phương thức cookie từ Illuminate\Http\Request:

$value = $request->cookie('name');

Gắn Cookies vào Responses

Bạn có thể gắp một cookie vào Illuminate\Http\Response bằng cách sử dụng phương thức cookie. Bạn có thể truyền tên, giá trị, và số phút cookie sẽ hết hạn vào phương thức:

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

Phương thức cookie ngoài ra còn có một vài đối sô ít được sử dụng. Nói chung, những đối số đó có cùng mục đích và ý nghĩa giống với đối số của setcookie của PHP:

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

Tạo Cookie Instances

Nếu bạn muốn tạo một Symfony\Component\HttpFoundation\Cookie có thể response sau một khoảng thời gian, bạn có thể sử dụng helper global cookie. Khi đó cookie sẽ không gửi lại cho client trừ khi nó được gán vào response instance:

$cookie = cookie('name', 'value', $minutes);
return response('Hello World')->cookie($cookie);

Files

Lấy Files Uploaded

Bạn có thể lấy files uploaded từ một Illuminate\Http\Request bằng cách sử dụng phương thức filehoặc sử dụng thuộc tính động. Phương thức file sẽ trả về một class Illuminate\Http\UploadedFile, nó kế thừa từ SplFileInfo class của PHP và cung cấp một số phương thức để tương tác với fiel:

$file = $request->file('photo');
$file = $request->photo;

Bạn có thể kiểm tra một file có tồn tại trên request hay không bằng cách dùng phương thức hasFile:

if ($request->hasFile('photo')) {
    //
}

Validate Uploads thành công

Ngoài việc kiểm tra file upload tồn tại, bạn có thể kiểm tra xem có vấn đề gì khi upload file bằng phương thức isValid:

if ($request->file('photo')->isValid()) {
    //
}

Đường dẫn File & Extensions

Class UploadedFile ngoài ra còn chưa phương thức lấy đường dẫn đầy đủ và extension của file. Phương thức extension sẽ cho phép đoán extension trên dựa nội dung của file. Extension này có thể khác với extension được cung cấp bởi client:

$path = $request->photo->path();
$extension = $request->photo->extension();

Phương thức khác của File

Có một số phương thức tồn tại trong class UploadedFile. Chi tiết xem tại tài liệu API của class để biết thêm chi tiết các phương thức đấy.

Lưu Files Uploaded

Để lưu một file uploaded, thông thường sử dụng một trong những cấu hình filesystems. Class UploadedFile có phương thức storenó sẽ chuyển file upload từ ổ cứng của bạn đến một nơi có thể là trên local của bạn hoặc ngay cả trên cloud storage như Amazon S3.

Phương thức store chấp nhận đường dẫn file nên được lưu trữ đường dẫn tương đối so với thư mục gốc cấu hình của filesystem. Đường dẫn không được chứa tên file, tên sẽ tự động được sinh ra bằng cách sử dụng mã hóa MD5 của nội dung file.

Phương thức store ngoài ra còn chấp nhận tham số thứ hai có tên của nơi mà bạn sử dụng để lưu file. Phương thức sẽ trả về đường dẫn tương đối của file đối với thư mục gốc:

$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');

Nếu bạn không muốn tên file được tự động tạo ra, bạn có thể sử dụng phương thứcstoreAs, nó sẽ chấp nhận các đối số như đường dẫn, tên file, và tên nơi lưu:

$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *