Response là các thông tin phản hồi cho người dùng. Qua đó biết được Request gửi tới Server có tình trạng như thế nào. Response thường gặp nhất đó là 404 khi bạn truy cập vào một địa chỉ website do mất kết nối thường xuất hiện 404. Trong Laravel tất cả các route
hay controller
đều phải trả về một response
. Laravel có cung cấp sẵn một Response class
để hỗ trợ chúng ta trả về các loại response data một cách đơn giản nhất. Lệnh Request có thể được viết tại Controller
hoặc route
1. Tạo response (Creating response)
# Chuỗi và mảng (String and array)
Mặc định, Khi một route, controller trả về giá trị là chuỗi thì Laravel sẽ tự động convert nó về dạng một HTTP response
routes/web.php
Route::get('/', function () {
return 'Hello World!';
});
Kết quả
Ngoài việc trả về chuỗi từ route hoặc controller , bạn có thể trả về một mảng. Laravel sẽ tự động chuyển mảng đó về JSON response
routes/web.php
Route::get('/', function () {
return [1, 2, 3];
});
Kết quả
# Đối tượng response (Response object)
Tuy nhiên, trong thực tế chúng ta lại cần trả về response với các header, status khác nhau. Lúc này bạn có thể sử dụng Response (Illuminate\Http\Response
) của Laravel. Đồng thời Laravel cũng có đưa Response class vào helper. Nên chúng ta hoàn toàn có thể sử dụng hàmresponse()
trong helper thay cho Response class để code được ngắn gọn hơn
Route::get('/', function () {
return response('Hello World', 200)->header('Content-Type', 'text/plain');
});
Ta đã thiết lập status code HTTP response là 200 thông qua tham số thứ hai của method response
. Ngoài ra còn đính kèm header Content-Type: text/plain
bằng phương thức header
kế tiếp
Kết quả
# Đính kèm header vào response (Attaching header to response)
Tất cả các method response có thể kết nối được, cho phép bạn xây dựng bất kỳ trường hợp response nào. Chẳng hạn bạn có thể thêm hàng loạt header với method header
trước khi trả về người dùng
return response($content)
->header('Content-Type', $type)
->header('X-Header-One', 'Header Value')
->header('X-Header-Two', 'Header Value');
Hoặc thay vì kết nối nhiều method như vậy, bạn có thể sử dụng method withHeaders
để truyền nhiều header dưới dạng mảng
return response($content)
->withHeaders([
'Content-Type' => $type,
'X-Header-One' => 'Header Value',
'X-Header-Two' => 'Header Value',
]);
# Đính kèm cookie cho response (Attaching cookie to response)
Nếu bạn muốn thêm cookie vào response bạn có thể sử dụng phương thức cookie
với cú pháp truyền vào tương tự như đối với hàm setcookie
của PHP
return response($content)->cookie('name', 'value', $minutes);
Nếu bạn muốn xóa một cookie nào đó trong response bạn có thể sử dụng phương thức withoutCookie
return response('Hello World')->withoutCookie('name');
2. Chuyển hướng (Redirect)
Đối với trường hợp bạn muốn trả về một redirect response, Laravel cũng có sẵn cho bạn một class Illuminate\Http\RedirectResponse
để làm điều đó. Đồng thời Laravel cũng đã đưa nó vào helper
để tiện cho việc sử dụng. Chúng ta có thể sử dụng helper redirect
thay cho class trên
# Chuyển hướng đến URI (Redirecting to URI)
Ví dụ: Redirect về URL /home/dashboard
khi người dùng vào URL /dashboard
Route::get('/dashboard', function () {
return redirect('home/dashboard');
});
Thỉnh thoảng bạn muốn khi người dùng submit form mà bị lỗi thì chuyển về trang trước để người dùng kiểm tra lại. Chúng ta sử dụng method back
, cùng với withInput
để đáp ứng yêu cầu trên
Route::post('/user/profile', function () {
// Validate the request...
return back()->withInput();
});
# Chuyển hướng đến route được đặt tên (Redirecting to named route)
Cú pháp:
return redirect()->route('name_route');
Ví dụ:
Route::get('/', function() {
return redirect()->route('home');
});
Route::get('/home', function() {
return 'Home page';
})->name('home');
Khi mình truy cập route /
thì sẽ redirect đến route có name là home
Nếu URI route của bạn chứa tham số, bạn có thể truyền dữ liệu thông qua tham số thứ hai dưới dạng mảng
Route::get('/', function() {
return redirect()->route('profile', ['id' => 1]);
});
Route::get('/profile/{id}', function($id) {
return 'Profile '. $id;
})->name('profile');
Khi truy cập: http://localhost:8000
. Kết quả là: Profile 1
Nếu bạn không muốn truyền giá trị ID theo mặc định, bạn có thể thay đổi bằng cách khai báo phương thức getRouteKey
ở trong file model để thay đổi key ID mặc định
public function getRouteKey()
{
return $this->slug;
}
# Chuyển hướng đến controller action (Redirecting to controller action)
Bạn có thể tạo chuyển hướng đến route chứa controller action thông qua method action
. Việc của bạn là chỉ cần truyền tên controller và tên method chứa trong route muốn chuyển đến
App/Http/Controllers/HomeController.php
<?php
namespace App\Http\Controllers;
class HomeController extends Controller
{
public function show()
{
return "Home page";
}
}
?>
routes/web.php
use App\Http\Controllers\HomeController;
Route::get('/', function() {
return redirect()->action([HomeController::class, 'show']);
});
Route::get('/home', [HomeController::class, 'show']);
Khi truy cập: http://localhost:8000
. sẽ chuyển hướng đến http://localhost:8000/home
. Kết quả là: Home page
# Chuyển hướng đến tên miền bên ngoài (Redirecting to external domain)
return response()->away('https://google.com');
# Chuyển hướng với flash session (Redirecting with flash session)
Redirect đến một URL mới và flash session thường được thực hiện cùng một lúc. Chẳng hạn bây giờ mình đăng ký hai route như sau:
routes/web.php
Route::get('/', function() {
return redirect('home')->with('name', 'John');
});
Route::get('/home', function() {
return view('home');
});
Tại action của route /
, ta thực thi chuyển hướng đến URI /home
, đồng thời thực hiện flash session với method with
. Sau khi chuyển hướng thì flash session data được thiết lập, lúc này bạn chỉ cần lấy nó ra và sử dụng thôi
resources/views/home.blade.php
<h3>
@if (session('name'))
Welcome, {{ session('name') }}
@else
Welcome
@endif
</h3>
Khi truy cập: http://localhost:8000
. sẽ chuyển hướng đến http://localhost:8000/home
. Kết quả là: John
Còn nếu truy cập thẳng đến http://localhost:8000/home
. Kết quả là: Welcome
3. Các loại response khác (Other response types)
Nếu bạn cần kiểm soát status code
và header
của và cũng muốn trả lại nội dung của response
, bạn nên sử dụng method view
:
Cú pháp:
return response()
->view('hello', $data, 200)
->header('Content-Type', $type);
$data: Dữ liệu truyền vào views
200: status code
Ví dụ
routes/web.php
Route::get('/', function() {
return response()->view('hello', $data = ['name'=>'John'], 200)
});
resources/views/hello.blade.php
<h3>Hello {{ $name }}</h3>
Kết quả
# JSON response
Phương thức json
sẽ tự động set Content-type: application/json
, chuyển đổi các mảng về dạng JSON sử dụng phương thức json_encode
của PHP
routes/web.php
Route::get('/', function() {
return response()->json([
'name' => 'Nguyễn Văn Hứa',
'state' => 'VN'
]);
});
Kết quả
Nếu muốn tạo JSONP response, bạn có thể sử dụng phương thức json
cùng với withCallback
Route::get('/', function(Request $request) {
return response()
->json(['name' => 'Abigail', 'state' => 'CA'])
->withCallback($request->input('callback'));
});
# Download file
Method download
thường được sử dụng để tạo một response bắt buộc người dùng download một file tại đường dẫn nhất định
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
Trong đó:
$pathToFile
là path đến file bạn muốn trả về.$name
là tên của file bạn muốn trả về.$headers
là các header bạn muốn trả về kèm theo
Ví dụ: download file resources/views/abc.blade.php
Route::get('/download', function() {
return response()->download('../resources/views/abc.blade.php');
});
Nếu bạn muốn một cái tên khác khi download, có thể thêm tham số thứ hai như sau:
Route::get('/download', function() {
return response()->download('../resources/views/abc.blade.php','other_file.php');
});
Bạn có thể khai báo các header theo dạng cấu trúc mảng
$headers = [
'X-Header-One' => 'Header value 1',
'X-Header-Two' => 'Header value 2',
// ...
];
Ngoài ra bạn có thể xóa file ngay sau khi người dùng download bằng cách sử dụng method deleteFileAfterSend
return response()->download($pathFile, $nameFile, $headers)->deleteFileAfterSend();
# Streamed download
Đôi khi bạn muốn trả về một nội dung nào đó có thể download được, nhưng lại không muốn ghi chúng vào ổ trước khi download. Bạn có thể sử dụng method streamDownload
để trả về một stream data
return response()->streamDownload(Closure, $nameFile, $headers);
Trong đó:
Closure
có nhiệm vụ thực hiện xử lý đểecho
nội dung cho file.$name:
Tham số thứ hai là tên file download.$headers:
Tham số thứ ba (tùy chọn) là các thiết lập header
routes/web.php
Route::get('/stream', function() {
return response()->streamDownload(function() {
echo 'Nguyễn Văn Hứa';
}, 'users.txt');
});
Lưu ý: Bắt buộc phải dùng lệnh echo
thì nội dung mới ghi được trên file download. Nội dung của file chỉ được là dạng text
Nội dung file users.txt sau khi tải về sẽ là: Nguyễn Văn Hứa
# File response
Nếu bạn muốn trả về response của các image, pdf… để hiển thị trên trình duyệt người dùng thay vì tải về, bạn có thể sử dụng method file
return response()->file($pathFile, $headers);
Trong đó:
- $pathFile: path file cần hiển thị
- $headers: tùy chọn chứa mảng thiết lập header response
Lưu ý: Base path của đường dẫn file trong method file
cũng là public
giống như method download
Ví dụ: Thêm một ảnh cai-dat-laravel.png
vào folder public
routes/web.php
Route::get('/image', function() {
return response()->file('cai-dat-laravel.png');
});
Kết quả
# Reponse macro
Nếu bạn muốn định nghĩa một response
tùy chỉnh mà bạn có thể sử dụng lại trong nhiều routes
và controllers
của mình, bạn có thể sử dụng method macro
Bạn có thể tạo một service provider với tên ResponseMacroServiceProvider
tại method boot
bạn sẽ thực hiện việc định nghĩa các custom response
Ví dụ: Tạo một response
để có thể trả về chuỗi in hoa, mình sẽ đăng ký với macro
như sau:
App/providers/ResponseMacroServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
class ResponseMacroServiceProvider extends ServiceProvider {
public function boot()
{
Response::macro('caps', function ($value) {
return Response::make(strtoupper($value));
});
}
}
?>
Method Response::macro
: dùng để định nghĩa một custom response
- Tham số thứ nhất sẽ là tên của custom response.
- Tham số thứ hai sẽ là một Closure, nhận dữ liệu truyền về qua
$value.
Method Response::make
: dùng để tạo response, nó sẽ nhận tham số là các chuỗi xử lý $value
trước khi được trả về.
Liệt kệ service provider vừa tạo trong config/app.php
'providers' => [
...
App\Providers\ResponseMacroServiceProvider::class
],
Giờ đây có thể sử dụng response caps
như những các loại response khác.
routes/web.php
Route::get('caps/{str}', function($str) {
return response()->caps($str);
})
Kết quả
Leave a Comment