Câu hỏi này đụng đúng “core design” của Laravel luôn — và thực ra Laravel có cho phép gọi từ constructor, nhưng họ không khuyến khích lạm dụng.
class UserController extends Controller
{
protected $service; public function __construct(UserService $service)
{
$this->service = $service;
}
}
➡️ Laravel container sẽ resolve UserService ngay khi khởi tạo controller
👉 Đây là cách chuẩn (DI – Dependency Injection)
Dù bạn gọi action nào:
GET /users/index GET /users/show
➡️ __construct() vẫn chạy
➡️ Tất cả dependency bị resolve hết
Giả sử:
public function __construct(
HeavyService $heavy,
RedisService $redis,
ElasticsearchService $es
) {}
➡️ Mỗi request:
❌ Ngay cả khi action không dùng
public function index(UserService $service)
{
return $service->getList();
}
👉 Chỉ khi gọi index() → mới resolve
$service = app(UserService::class);
👉 Chủ động control thời điểm
Ví dụ:
👉 Không nên chạy ngay khi request vào
Constructor inject nhiều thứ:
| Cách dùng | Ưu điểm | Nhược điểm |
|---|---|---|
| Constructor injection | Clean, chuẩn OOP | Load hết từ đầu |
| Method injection | Lazy, tối ưu | Dài param |
| app() resolve | Linh hoạt | Ít “clean” hơn |
👉 Với hệ thống nhỏ:
👉 Với hệ thống lớn / MMO / crawler / high-load (case của bạn):
__construct(Logger $logger)
public function crawl(CrawlerService $crawler)
Không phải “không gọi từ constructor”
👉 mà là:
❗ Đừng resolve mọi thứ quá sớm
Laravel thiết kế container để: