Ключевые понятия
Пять идей, из которых следует всё остальное. Прочитав эту страницу, вы поймёте, как устроен любой Winter-проект и куда смотреть дальше.
Стереотипы
Приложение собирается из классов-стереотипов — базовых классов с чёткой ролью. Вы наследуетесь от нужного, а фреймворк знает, как его обнаружить и вызвать.
| Стереотип | Роль | База |
|---|---|---|
Controller |
Принимает HTTP-запрос, возвращает ответ | Stereotype\Controller |
Service |
Бизнес-логика | Stereotype\Service |
Repository |
Доступ к данным (PPA/ORM) | Ppa\Stereotype\Repository |
Middleware |
Обработка до/после контроллера | Stereotype\Middleware |
Job |
Фоновая задача | Stereotype\Job |
Cmd / CmdCustom |
Консольная команда | Console\Inc\Cmd |
Типичный поток запроса: Controller → Service → Repository. Стереотипы создаёт
генератор call make.
Атрибуты вместо конфигов
Winter описывает поведение атрибутами прямо на классах, методах и свойствах — регистрировать что-либо вручную не нужно.
#[RequestMapping('users')] // префикс маршрутов класса
class UserController extends Controller
{
#[Autowired] private UserService $service; // внедрение зависимости
#[GetMapping('{id}')] // маршрут GET /users/{id}
public function show(#[PathVariable] int $id): ResponseEntity
{
return ResponseEntity::ok($this->service->find($id));
}
}Те же принципы работают для привязки запроса (#[RequestJson],
#[RequestQuery]…), валидации (#[Valid], #[NotBlank]…) и маппинга ORM
(#[Table], #[Id], #[Varchar]…).
Внедрение зависимостей (DI)
Контроллеры, сервисы, репозитории, команды и джобы создаются через
DI-контейнер. Зависимости приходят через конструктор или свойство с #[Autowired]
— вы не вызываете new руками.
Три жизненных цикла: #[Singleton] (один на процесс), #[Request] (один на
запрос), #[Transient] (каждый раз новый). Подробности и ручные привязки —
в пакете Winter DI.
Конфигурация: Boot
Вся настройка проекта — в одном файле bootstrap.php, в классе
Boot extends BaseBoot. Вы переопределяете только нужные хуки; порядок вызова
фиксирован:
1. configure() → Kernel::init(): пути, .env, логирование, таймзона
2. DI scan → автопоиск #[Singleton] / #[Request] / #[Transient]
3. providers($c) → ручные привязки, фабрики, значения
4. channels() → доп. каналы логов
5. plugins() → подприложения с префиксом маршрута
6. httpCors() → глобальная политика CORS
7. health() → эндпоинты /actuatorВсе хуки, кроме configure(), опциональны — по умолчанию это разумные no-op’ы.
Подробно — в Конфигурации.
Точки входа
Один и тот же Boot обслуживает все рантаймы — меняется лишь вызываемый метод:
| Файл | Рантайм | Тело |
|---|---|---|
public/index.php |
PHP-FPM / dev-сервер | Boot::web() |
server.php |
Swoole HTTP | Boot::swoole() |
call |
CLI | Boot::cli($argv) |
wKernelExecutor |
Исполнитель задач | Boot::executor($argv) |
Собираем вместе
Запрос GET /users/1 проходит так:
public/index.php → Boot::web()
→ Router резолвит #[GetMapping('{id}')] в UserController
→ DI создаёт контроллер и внедряет UserService
→ #[PathVariable] привязывает id = 1
→ метод возвращает ResponseEntity::ok(...)
→ ответ отправляется клиентуДальше
- Установка — создать проект
- Быстрый старт — пройти этот поток руками
- Структура проекта — где что лежит