Контроллеры
Контроллеры служат для группировки связанной логики обработки HTTP-запросов в одном классе. Они располагаются в каталоге app/Http/Controllers и наследуются от базового класса App\Http\Controllers\Controller.
Создание контроллеров
Базовый контроллер
Базовый контроллер содержит общую логику, которую могут наследовать другие контроллеры. Пример контроллера с одним действием:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
public function show($id)
{
$user = User::findOrFail($id);
return view('users.show', compact('user'));
}
}
Для маршрутизации к методу контроллера используйте:
use App\Http\Controllers\UserController;
Route::get('/user/{id}', [UserController::class, 'show']);
Примечание: Контроллеры не обязаны наследовать базовый класс, но без него вы потеряете доступ к удобным функциям, таким как
middleware.
Контроллеры одного действия (Invokable)
Для сложных операций можно создать контроллер с единственным методом __invoke:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Services\ProvisioningService;
class ProvisionServer extends Controller
{
public function __invoke(ProvisioningService $service)
{
$server = $service->provision();
return response()->json($server, 201);
}
}
Регистрация маршрута для такого контроллера:
use App\Http\Controllers\ProvisionServer;
Route::post('/server', ProvisionServer::class);
Создание контроллеров через консоль
Используйте консольные команды для быстрого создания контроллеров:
# Обычный контроллер
php imhotep make:controller UserController
# Контроллер одного действия
php imhotep make:controller ProvisionServer --invokable
Внедрение зависимостей
Контроллеры автоматически разрешаются контейнером Imhotep, что позволяет использовать внедрение зависимостей.
Внедрение в конструктор
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
use App\Services\EmailService;
class UserController extends Controller
{
protected $users;
protected $emailService;
public function __construct(UserRepository $users, EmailService $emailService)
{
$this->users = $users;
$this->emailService = $emailService;
}
}
Внедрение в методы
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Imhotep\Http\Request;
use Imhotep\Validation\Validator;
class UserController extends Controller
{
public function store(Request $request, Validator $validator)
{
$validated = $validator->validate($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|email',
]);
$user = $this->users->create($validated);
return response()->json($user, 201);
}
}
Параметры маршрутов и зависимости
Если метод ожидает параметры маршрута, укажите их после зависимостей:
// Маршрут
Route::put('/user/{userId}', [UserController::class, 'update']);
// Контроллер
public function update(Request $request, UserRepository $repository, $userId)
{
$user = $repository->findOrFail($userId);
$user->fill($request->validated());
$repository->update($user);
return response()->json($user);
}
Middleware в контроллерах
Вы можете определять middleware непосредственно в контроллере:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Closure;
use Imhotep\Http\Request;
class UserController extends Controller
{
public function __construct()
{
// Применить ко всем методам
$this->middleware('auth');
// Только к указанным методам
$this->middleware('log')->only(['index', 'show']);
// Ко всем, кроме указанных
$this->middleware('subscribed')->except(['create', 'store']);
// С параметрами
$this->middleware('role:admin')->only('admin');
// Через замыкание
$this->middleware(function (Request $request, Closure $next) {
if (! $request->user()->isActive()) {
abort(403, 'Account is not active');
}
return $next($request);
})->only('dashboard');
}
}