Контроллеры необходимы для группировки связанной логики обработки запросов в одном классе.
По умолчанию, все контроллеры хранятся в каталоге app/Http/Controllers, где так же находится базовый класс App\Http\Controllers\Controller, включенный в Imhotep. Рассмотрим пример обычного контроллера:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
public function show($id)
{
return "User-{$id}";
}
}
Вы можете определить маршрут к этому методу контроллера следующим образом:
use App\Http\Controllers\UserController;
Route::get('/user/{id}', [UserController::class, 'show']);
Когда входящий запрос совпадает с указанным URI маршрута, будет вызван метод show класса App\Http\Controllers\UserController, и параметры маршрута будут переданы методу.
Контроллеры не требуют расширения базового класса. Однако у вас не будет доступа к удобным функциям, например middleware.
Если действие контроллера является сложным, вы можете посвятить целый класс этому единственному действию. Для этого вы можете определить в контроллере один метод __invoke:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class ProvisionServer extends Controller
{
public function __invoke()
{
// ...
}
}
При регистрации маршрутов для контроллеров одиночного действия вам не нужно указывать метод контроллера. Вместо этого вы можете просто передать имя контроллера:
use App\Http\Controllers\ProvisionServer;
Route::post('/server', ProvisionServer::class);
Для создания обычного контроллера через консоль, используйте следующую команду:
php imhotep make:controller UserController
Для создания одиночного контроллера:
php imhotep make:controller ProvisionServer --invokable
Используя метод middleware в конструкторе вашего контроллера, вы можете назначить middleware действиям контроллера:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
}
Вы также можете назначать middleware через замыкания. Это позволяет использовать уникальные middleware для конкретного контроллера, без создания отдельного целого класса middleware:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
public function __construct()
{
$this->middleware(function ($request, $next) {
// Необходимые действия
return $next($request);
});
}
}
Контейнер Imhotep используется для извлечения всех контроллеров. Это позволяет объявлять любые зависимости необходимые вашему контроллеру в его конструкторе:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
protected $users;
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
Вы также можете объявлять необходимые вам зависимости и в методах контроллера:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
public function store(Request $request)
{
$name = $request->name;
}
}
Если метод контроллера ожидает входные данные из параметров маршрута, укажите аргументы после другим зависимостей, например, если маршрут зарегистрирован так:
use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);
То контроллер будет выглядеть следующим образом:
namespace App\Http\Controllers;
use Imhotep\Http\Request;
class UserController extends Controller
{
public function update(Request $request, $userId)
{
// ...
}
}