Giao diện
Controllers
Giới thiệu (Introduction)
Thay vì định nghĩa tất cả logic xử lý request bằng closures trong route files, bạn có thể tổ chức hành vi này bằng "controller" classes. Controllers nhóm logic xử lý request liên quan vào một class duy nhất. Ví dụ, UserController xử lý tất cả requests liên quan đến users: hiển thị, tạo, cập nhật, xóa. Mặc định, controllers nằm trong thư mục app/Http/Controllers.
Viết Controllers (Writing Controllers)
Controller cơ bản (Basic Controllers)
Tạo controller mới bằng lệnh Artisan:
bash
php artisan make:controller UserControllerVí dụ controller cơ bản:
php
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\View\View;
class UserController extends Controller
{
/**
* Hiển thị profile của user.
*/
public function show(string $id): View
{
return view('user.profile', [
'user' => User::findOrFail($id)
]);
}
}Đăng ký route cho controller:
php
use App\Http\Controllers\UserController;
Route::get('/user/{id}', [UserController::class, 'show']);Single Action Controllers
Nếu controller action phức tạp, bạn có thể dành toàn bộ class cho một action duy nhất bằng method __invoke:
php
<?php
namespace App\Http\Controllers;
class ProvisionServer extends Controller
{
/**
* Provision web server mới.
*/
public function __invoke()
{
// ...
}
}Khi đăng ký route, không cần chỉ định method:
php
use App\Http\Controllers\ProvisionServer;
Route::post('/server', ProvisionServer::class);Tạo invokable controller:
bash
php artisan make:controller ProvisionServer --invokableController Middleware
Middleware có thể gán cho controller routes trong route files:
php
Route::get('/profile', [UserController::class, 'show'])->middleware('auth');Hoặc chỉ định middleware trong class controller bằng cách implement interface HasMiddleware:
php
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
class UserController implements HasMiddleware
{
/**
* Lấy middleware cho controller.
*/
public static function middleware(): array
{
return [
'auth',
new Middleware('log', only: ['index']),
new Middleware('subscribed', except: ['store']),
];
}
// ...
}Cũng có thể định nghĩa middleware bằng closures:
php
use Closure;
use Illuminate\Http\Request;
public static function middleware(): array
{
return [
function (Request $request, Closure $next) {
return $next($request);
},
];
}Resource Controllers
Nếu xem mỗi Eloquent model là "resource", bạn thường thực hiện cùng tập hành động CRUD. Laravel resource routing gán các routes CRUD cho controller chỉ với một dòng code:
bash
php artisan make:controller PhotoController --resourceĐăng ký resource route:
php
use App\Http\Controllers\PhotoController;
Route::resource('photos', PhotoController::class);Actions của Resource Controller
| Verb | URI | Action | Route Name |
|---|---|---|---|
| GET | /photos | index | photos.index |
| GET | /photos/create | create | photos.create |
| POST | /photos | store | photos.store |
| GET | /photos/{photo} | show | photos.show |
| GET | /photos/{photo}/edit | edit | photos.edit |
| PUT/PATCH | /photos/{photo} | update | photos.update |
| DELETE | /photos/{photo} | destroy | photos.destroy |
Đăng ký nhiều resource controllers cùng lúc:
php
Route::resources([
'photos' => PhotoController::class,
'posts' => PostController::class,
]);Partial Resource Routes
Chỉ định tập con actions:
php
Route::resource('photos', PhotoController::class)->only([
'index', 'show'
]);
Route::resource('photos', PhotoController::class)->except([
'create', 'store', 'update', 'destroy'
]);API Resource Routes
Loại bỏ routes create và edit (không cần cho API):
php
Route::apiResource('photos', PhotoController::class);
// Nhiều API resources
Route::apiResources([
'photos' => PhotoController::class,
'posts' => PostController::class,
]);Tạo API resource controller:
bash
php artisan make:controller PhotoController --apiSingleton Resource Controllers
Cho resources chỉ có một instance (ví dụ: profile, thumbnail):
php
use App\Http\Controllers\ProfileController;
Route::singleton('profile', ProfileController::class);Routes được đăng ký:
| Verb | URI | Action | Route Name |
|---|---|---|---|
| GET | /profile | show | profile.show |
| GET | /profile/edit | edit | profile.edit |
| PUT/PATCH | /profile | update | profile.update |
Singleton resources có thể lồng nhau:
php
Route::singleton('photos.thumbnail', ThumbnailController::class);Creatable Singleton Resources
Thêm routes creation và storage:
php
Route::singleton('photos.thumbnail', ThumbnailController::class)->creatable();API singleton:
php
Route::apiSingleton('profile', ProfileController::class);Dependency Injection và Controllers
Constructor Injection
Laravel service container phân giải tất cả controllers, cho phép type-hint dependencies trong constructor:
php
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
public function __construct(
protected UserRepository $users,
) {}
}Method Injection
Type-hint dependencies trong methods — use case phổ biến là inject Illuminate\Http\Request:
php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request): RedirectResponse
{
$name = $request->name;
// Lưu user...
return redirect('/users');
}
}Nếu method cũng nhận route parameter, liệt kê route arguments sau dependencies:
php
Route::put('/user/{id}', [UserController::class, 'update']);php
public function update(Request $request, string $id): RedirectResponse
{
// Cập nhật user...
}