Controllers
مدیریت منطق کسب و کار و درخواستها در Controllerها
Controllerها کلاسهایی هستند که منطق کسب و کار را مدیریت میکنند و درخواستها را پردازش میکنند. آنها پل ارتباطی بین routes و models هستند و مسئولیت تبدیل درخواستهای HTTP به actions مناسب را بر عهده دارند.
وظایف Controller:
- دریافت و پردازش درخواستهای HTTP
- اعتبارسنجی دادهها با استفاده از Form Requests
- فراخوانی Service classes و Model methods
- مدیریت session و flash messages
- بازگرداندن Response (View، JSON، Redirect)
- مدیریت errors و exceptions
اصول طراحی Controller:
- <strong>Thin Controllers, Fat Models</strong>: منطق کسب و کار باید در Service classes یا Models باشد، نه در Controller
- <strong>Single Responsibility</strong>: هر Controller باید یک resource را مدیریت کند
- <strong>Dependency Injection</strong>: استفاده از DI برای وابستگیها
- <strong>Form Request Validation</strong>: استفاده از Form Requests برای validation
- <strong>Resource Controllers</strong>: استفاده از Resource Controllers برای RESTful operations
انواع Controller:
- <strong>Basic Controllers</strong>: Controllerهای ساده با methods دلخواه
- <strong>Resource Controllers</strong>: Controllerهای RESTful با methods استاندارد
- <strong>API Controllers</strong>: Controllerهای مخصوص API با JSON responses
- <strong>Single Action Controllers</strong>: Controllerهای تک action با __invoke method
مثالها
Controller ساده
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}
public function show(User $user)
{
return view('users.show', compact('user'));
}
}
یک Controller ساده که کاربران را نمایش میدهد.
Controller با Dependency Injection
<?php
namespace App\Http\Controllers;
use App\Services\UserService;
use App\Http\Requests\StoreUserRequest;
class UserController extends Controller
{
public function __construct(
private UserService $userService
) {}
public function store(StoreUserRequest $request)
{
$user = $this->userService->createUser($request->validated());
return redirect()->route('users.show', $user)
->with('success', 'User created successfully');
}
}
Controller با dependency injection و Form Request validation.
API Controller
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
class UserController extends Controller
{
public function __construct(
private UserService $userService
) {}
public function index(): JsonResponse
{
$users = $this->userService->getAllUsers();
return response()->json([
'data' => $users,
'message' => 'Users retrieved successfully'
]);
}
public function show(int $id): JsonResponse
{
$user = $this->userService->getUserById($id);
return response()->json([
'data' => $user,
'message' => 'User retrieved successfully'
]);
}
}
API Controller که JSON response برمیگرداند.
Single Action Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ShowProfileController extends Controller
{
public function __invoke(Request $request)
{
return view('profile', [
'user' => $request->user()
]);
}
}
// Route:
// Route::get('/profile', ShowProfileController::class);
Single Action Controller با __invoke method.
Controller با Middleware
<?php
namespace App\Http\Controllers;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth')->except(['index', 'show']);
$this->middleware('admin')->only(['destroy']);
$this->middleware('throttle:60,1')->only(['store']);
}
public function index()
{
// Public access
}
public function store()
{
// Requires auth, rate limited
}
public function destroy()
{
// Requires auth and admin role
}
}
اعمال middleware در constructor.
Controller با Response Helpers
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
return view('users.index', ['users' => User::all()]);
}
public function store(Request $request)
{
// Redirect with message
return redirect()->route('users.index')
->with('success', 'User created');
}
public function update(Request $request, User $user)
{
// JSON response
return response()->json([
'message' => 'User updated',
'user' => $user
]);
}
public function destroy(User $user)
{
// Redirect back
return back()->with('success', 'User deleted');
}
}
استفاده از response helpers برای انواع مختلف response.
Controller با Service Layer
<?php
namespace App\Http\Controllers;
use App\Services\OrderService;
use App\Http\Requests\StoreOrderRequest;
class OrderController extends Controller
{
public function __construct(
private OrderService $orderService
) {}
public function store(StoreOrderRequest $request)
{
try {
$order = $this->orderService->createOrder(
$request->validated(),
$request->user()
);
return redirect()->route('orders.show', $order)
->with('success', 'Order created successfully');
} catch (\Exception $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
}
Controller با service layer که business logic را handle میکند.
Controller Testing
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\User;
class UserControllerTest extends TestCase
{
public function test_index_returns_users()
{
User::factory()->count(3)->create();
$response = $this->get('/users');
$response->assertStatus(200);
$response->assertViewIs('users.index');
$response->assertViewHas('users');
}
public function test_store_creates_user()
{
$userData = [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'password123'
];
$response = $this->post('/users', $userData);
$response->assertRedirect();
$this->assertDatabaseHas('users', ['email' => 'john@example.com']);
}
}
Testing Controller با feature tests.
موارد استفاده
- مدیریت HTTP requests و responses
- اعتبارسنجی دادهها با Form Requests
- فراخوانی service classes برای business logic
- مدیریت session و flash messages
- بازگرداندن views، JSON یا redirects
- مدیریت errors و exceptions
اشتباهات رایج
- قرار دادن business logic در Controller که باید در Service باشد
- عدم استفاده از Form Requests برای validation
- Fat Controllers که Single Responsibility را نقض میکنند
- عدم استفاده از Dependency Injection
- Hard-coding logic که باید configurable باشد
- عدم handle کردن errors و exceptions
بهترین روشها
- از Thin Controllers استفاده کنید - logic را در Services قرار دهید
- از Form Requests برای validation استفاده کنید
- از Dependency Injection برای وابستگیها استفاده کنید
- از Resource Controllers برای RESTful operations استفاده کنید
- Response helpers را برای consistency استفاده کنید
- Errors و exceptions را به درستی handle کنید
- Controllerها را test کنید
موارد خاص
- Controller با complex business logic
- Controller با multiple dependencies
- Controller با conditional responses
- Controller در API که JSON response نیاز دارد
- Controller با file uploads
- Controller با long-running operations
نکات عملکرد
- Thin Controllers سریعتر از Fat Controllers هستند
- از eager loading برای relationships استفاده کنید
- از caching برای expensive operations استفاده کنید
- Response time میتواند با service layer optimization بهبود یابد
نکات امنیتی
- همیشه از Form Requests برای validation استفاده کنید
- Authorization checks را در Form Request یا Policy انجام دهید
- مطمئن شوید که sensitive data به درستی protected است
- از middleware برای authentication و authorization استفاده کنید
- Input sanitization را در validation انجام دهید
نکات مصاحبه
- تفاوت بین Thin و Fat Controller چیست؟
- چرا باید از Form Requests استفاده کرد؟
- Single Action Controller چیست و چه زمانی استفاده میشود؟
- چگونه میتوان Controller را test کرد؟
- تفاوت بین Web و API Controller چیست؟
- چرا باید business logic را در Controller قرار نداد؟
یادداشتهای نسخه
- Laravel 11.x: بهبود performance در Controller execution
- Laravel 11.x: پشتیبانی بهتر از type-hinted responses
- Laravel 10.x: بهبود resource controllers
- Laravel 9.x: بهبود single action controllers