Tìm hiểu Laravel (P10) - HTTP Requests
Bài đăng này đã không được cập nhật trong 7 năm
Indexs
- Phần 1: Cài đặt
- Phần 2: Form đăng nhập
- Phần 3: Send Mail
- Phần 4: Error page
- Phần 5: Application Structure
- Phần 6: Logging
- Phần 7: Routing
- Phần 8: Middleware
- Phần 9: Controller
- Ở bài trước ta đã cùng nhau tìm hiểu về
controller
và có nhắc khá nhiều đếnrequest
. Vì thế ở bài này ta sẽ tìm hiểu chi tiết vềHTTP Request
.
1. Truy cập vào Request
-
Để lấy đối tượng hiện tại của HTTP request thông qua dependency injection, ta cần type-hint vào class
Illuminate\Http\Request
trong class controller. Các request đến sẽ được tự động injected bởiservice container
:namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Store a new user. * * @param Request $request * @return Response */ 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:namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Update the specified user. * * @param Request $request * @param string $id * @return Response */ 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 classSymfony\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ứcpath
sẽ trả vềfoo/bar
:$uri = $request->path();
- Phươ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
orfullUrl
. Phương thứcurl
sẽ trả về URL không có string query, trong khi phương thứcfullUrl
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')) { // }
- Tiêu chuẩn của PSR-7 standard: tiêu chuẩn này 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) { // });
2. Lấy Input
-
Lấy tất cả dữ liệu Input:
- Ta 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();
- Ta 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
-
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 đượcinput
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');
- 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
-
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\Reques
. 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. Nếu nó không tìm thấy, Laravel laravel sẽ tìm trong tham số route.
- 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
-
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');
- 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:
-
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');
- 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ố:
-
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 has trả về true nếu giá trị tồn tại và không phải chuỗi rỗng:
if ($request->has('name')) { // }
- 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 has trả về true nếu giá trị tồn tại và không phải chuỗi rỗng:
Input cũ
- Laravel cho phép ta giữ giá trị input từ lần request cũ tới request tiếp theo. Nó rất có ích trong trường hợp ta muốn thiết lập lại form khi validate lỗi. Theo mặc định khi ta sử dụng validate của Laravel thì Laravel đã tự động làm việc này cho ta thông qua built-in validation của Laravel, việc của ta là dùng chúng sao cho hợp lý.
- Flashing Input tới Session:
- Phương thức
flash
trong classIlluminate\Http\Request
sẽ lưu input hiện tại vào trong session nên ta có thể dùng chúng trong request tiếp theo:$request->flash();
- Nhưng nếu bạn không muốn lưu những thông tin nhạy cảm vào session, chẳng hạn như password thì ta có thể làm như sau:
$request->flashOnly(['username', 'email']); $request->flashExcept('password');
- Phương thức
- Flashing Input rồi chuyển trang
- Đôi khi ta muốn flash input vào session rồi chuyển về trang trước đó, lúc này ta sẽ cần dùng phương thức
withInput
:return redirect('form')->withInput(); return redirect('form')->withInput( $request->except('password'); );
- Đôi khi ta muốn flash input vào session rồi chuyển về trang trước đó, lúc này ta sẽ cần dùng phương thức
- Lấy input cũ
- Để lấy flashed input từ request trước, ta sử dụng phương thức
old
củaRequest
. Phương thức này sẽ lấy dữ liệu flashed input từ trước ra khỏi session:$username = $request->old('username');
- Ngoài ra Laravel còn cung cấp sẵn một helper global
old
để ta có thể dễ dàng lấy ra input cũ từ view:<input type="text" name="username" value="{{ old('username') }}">
- Nếu không tìm thấy input cũ thì phương thức
old
sẽ trả vềnull
.
- Để lấy flashed input từ request trước, ta sử dụng phương thức
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');
- 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ị
-
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ứccookie
. 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 );
- Bạn có thể gắp một cookie vào
-
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);
- 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:
3. Files
3.1 Lấy Files Uploaded
-
Ta có thể lấy files uploaded từ một
Illuminate\Http\Request
bằng cách sử dụng phương thức file hoặc sử dụng thuộc tính động. Phương thức file sẽ trả về một classIlluminate\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 file:$file = $request->file('photo'); $file = $request->photo;
-
Dùng phương thức
hasFile
để kiểm tra một file có tồn tại trên request hay không: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()) { // }
- 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
-
Đườ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ứcextension
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();
- Class
3.2 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 trong file
app\config\filesystems.php
. ClassUploadedFile
có phương thứcstore
nó 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');
Tài liệu tham khảo Laravel HTTP Request
All rights reserved