Контроллеры

Контроллеры служат для группировки связанной логики обработки 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'));
    }
}
PHP

Для маршрутизации к методу контроллера используйте:

use App\Http\Controllers\UserController;

Route::get('/user/{id}', [UserController::class, 'show']);
PHP

Примечание: Контроллеры не обязаны наследовать базовый класс, но без него вы потеряете доступ к удобным функциям, таким как 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);
    }
}
PHP

Регистрация маршрута для такого контроллера:

use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);
PHP

Создание контроллеров через консоль

Используйте консольные команды для быстрого создания контроллеров:

# Обычный контроллер
php imhotep make:controller UserController

# Контроллер одного действия
php imhotep make:controller ProvisionServer --invokable
SHELL

Внедрение зависимостей

Контроллеры автоматически разрешаются контейнером 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;
    }
}
PHP

Внедрение в методы

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);
    }
}
PHP

Параметры маршрутов и зависимости

Если метод ожидает параметры маршрута, укажите их после зависимостей:

// Маршрут
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);
}
PHP

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');
    }
}
PHP