Установка
Winter — библиотека, а не каркас с обязательной структурой. Проект собирается из нескольких файлов, и ниже разобран каждый: что он делает и почему нужен. Если разбирать не хочется — первая же команда на этой странице даёт работающий проект.
Требования
| Требование | Значение |
|---|---|
| PHP | 8.4 или выше |
| Composer | 2.x |
| Расширения | ext-pcntl, ext-posix, ext-fileinfo |
| Для веб-приложения | ext-swoole |
Веб-слой работает только на Swoole
Winter не использует встроенный сервер PHP. Если приложение объявляет #[EnableWeb],
запуск требует расширение Swoole и без него откажется стартовать:
`call run` with a web tier needs ext-swoole (pecl install swoole).Это касается и режима разработки — он отличается только наблюдением за файлами, сервер тот же самый.
Приложению без веба — только процессы, демоны или планировщик — Swoole не обязателен.
Остальные расширения ставятся под конкретные задачи:
| Расширение | Зачем |
|---|---|
ext-pdo |
Доступ к базе данных |
ext-simplexml |
Разбор XML в теле запроса |
ext-bcmath, ext-decimal |
Точные числовые типы при привязке параметров |
ext-shmop |
Передача данных дочернему процессу через разделяемую память; без него используется канал |
Проверка окружения
php -v покажет версию, php -m — список расширений. Отсутствие swoole в этом
списке — самая частая причина, по которой первый запуск не удаётся.
Три пути
| Путь | Когда |
|---|---|
Готовый каркас — create-project |
Новый проект; нужен работающий скелет за одну команду |
| Через Docker | На машине нет PHP или нужных расширений |
С нуля — require winter-kernel |
Встраивание в существующий проект, своя раскладка, или желание понимать каждый файл |
Готовый каркас
composer create-project flytachi/winter my-app
cd my-app
php call run devComposer после установки сам доводит проект до рабочего состояния — это видно в его выводе:
> @php call storage init
| storage ..................................................... [CREATED]
| storage/cache ............................................... [CREATED]
| storage/logs ................................................ [CREATED]
> chmod -R 777 storage
> @php call cfg init
| .env ........................................................ [CREATED]
| Old key (empty)
| [✓] WINTER_KEY generated and saved to .env
| New key bf4ee7d770a565c21598e57e87d46fde6637c0181cac13f4c37fd7b4c194c652Каталоги созданы и доступны на запись, .env на месте, ключ — свой, а не общий с
чужим проектом. Ставить и настраивать больше нечего.
В каркасе ровно то же, что собирается вручную ниже: bootstrap.php с классом
приложения, файл call, PSR-4 Main\ → main/, готовый MainController и
monolog/monolog в require-dev — чтобы логи было куда писать сразу.
Дальше можно не читать
Если каркас подошёл, переходите к Быстрому старту. Разделы ниже — для тех, кому нужно собрать проект руками или понять, из чего он состоит.
Через Docker, если PHP нет
create-project — тоже PHP-программа, но запустить её можно в одноразовом контейнере:
образ несёт PHP внутри, а проект остаётся у вас в примонтированном каталоге.
docker run --rm -v "$PWD":/app -w /app composer:2 \
create-project flytachi/winter my-app --ignore-platform-reqs--ignore-platform-reqs нужен потому, что ядро требует ext-pcntl и ext-posix —
они нужны работающему приложению, а не установщику, и в рабочем образе они есть.
Дальше проект поднимается своим контейнером, где Swoole уже собран, а консольные команды выполняются тем же одноразовым способом. Подробно, с командами — в Быстром старте.
Сборка проекта с нуля
1. Каталог и зависимость
mkdir my-app && cd my-app
composer require flytachi/winter-kernel2. Каталог кода и автозагрузка
Winter ничего не навязывает: каталог и пространство имён выбираете вы — дальше в
примерах это main/ и Main\.
mkdir mainТеперь свяжите их в composer.json:
{
"autoload": {
"psr-4": {
"Main\\": "main/"
}
},
"require": {
"php": ">=8.4",
"flytachi/winter-kernel": "^4.0"
}
}composer dump-autoload3. Класс приложения — bootstrap.php
Это единственный файл настройки. Он подключает автозагрузчик и объявляет, из чего состоит приложение:
<?php
declare(strict_types=1);
use Flytachi\Winter\Kernel\App\Attribute\EnableWeb;
use Flytachi\Winter\Kernel\WinterApplication;
require __DIR__ . '/vendor/autoload.php';
#[EnableWeb]
final class Application extends WinterApplication
{
public static function main(array $argv): never
{
parent::run($argv);
}
}Хуков, которые нужно переопределять, здесь нет — всё остальное живёт в обычных классах,
которые находит сканер. Что можно объявить помимо #[EnableWeb] — на странице
Состав приложения.
Каталог этого файла становится корнем проекта: от него отсчитываются .env, storage/,
resources/ и начало обхода файлов.
4. Файл запуска — call
Через него идут все команды, включая запуск сервера:
#!/usr/bin/env php
<?php
if (PHP_VERSION_ID < 80400) {
echo "Please use PHP version 8.4 or higher. Current: " . PHP_VERSION . "\n";
exit(1);
}
chdir(__DIR__);
require './bootstrap.php';
Application::main($argv);chmod +x callchdir() здесь обязателен: он привязывает относительные пути — .env, storage/,
resources/ — к каталогу проекта, а не к тому, откуда вы вызвали команду.
5. Окружение и каталоги
php call cfg init # .env из шаблона + свежий WINTER_KEY
php call storage init # служебные каталоги внутри storage/Получившийся .env минимален:
WINTER_KEY=<сгенерированный ключ>
TIME_ZONE=UTC
DEBUG=trueОстальные переменные — база, логи, параметры сервера — добавляются по мере надобности, см. Конфигурацию.
6. Первый контроллер
php call make -c .Main # → main/MainController.phpГенератор создаёт рабочую заготовку: метод hello() с атрибутом #[RequestMapping]
без аргументов. Такой атрибут монтирует метод по имени класса и отвечает на все
основные HTTP-методы — проверить можно, не открывая файл:
php call mapping show | [ Routes (5) ]
| GET /main → Main\MainController::hello
| POST /main → Main\MainController::hello
| PUT /main → Main\MainController::hello
| PATCH /main → Main\MainController::hello
| DELETE /main → Main\MainController::hello
| [ Routes ]Что получилось
my-app/
├── bootstrap.php — класс приложения: из чего оно состоит
├── call — точка входа для всех команд
├── composer.json — автозагрузка и зависимости
├── .env — окружение
├── main/ — ваш код
└── storage/ — служебные каталогиКаталог resources/ для шаблонов и переводов появится, когда понадобится. Что за что
отвечает — Структура проекта.
Первый запуск
php call run devСервер слушает порт 8000 на всех интерфейсах.
Открывать нужно /main, а не /
Корень / не отвечает, пока вы сами не объявите там маршрут, — на него приходит
честный 404 Not Found [ GET / ]. Сгенерированный контроллер живёт по адресу
http://localhost:8000/main; какие пути заняты, всегда показывает
php call mapping show.
Слово dev включает наблюдение за файлами: при изменении любого .php приложение
перезапускается само. В рабочем режиме запускают без него — php call run.
Адрес и порт переопределяются флагами:
php call run dev --port=9000
php call run dev --host=127.0.0.1 --port=9000 # только локальноЧто делает cfg init
Команда одна, а действий несколько — их стоит знать, потому что одно из них необратимое.
| Действие | Подробности |
|---|---|
Приводит composer.json в порядок |
name → project/<каталог>, description → My Project <каталог>, удаляет keywords, scripts, чистит authors |
Создаёт .env |
Из шаблона, если файла ещё нет; существующий не трогает |
Генерирует WINTER_KEY |
Каждый раз заново, поверх текущего |
| Кладёт файл подсказок для PhpStorm | vendor/.phpstorm.meta/.phpstorm.meta.php |
На существующем проекте cfg init не запускают
Ключ перевыпускается безусловно, а WINTER_KEY подписывает данные, которые ядро
передаёт дочерним процессам. Процессы и демоны, запущенные со старым ключом, после
смены не пройдут проверку подписи.
Нужны отдельные шаги — берите отдельные команды: cfg env -i создаст .env,
cfg key -g перевыпустит ключ осознанно.
Склонировали существующий проект
После git clone каркас уже есть, но всё, что не попадает в репозиторий, нужно создать
заново:
composer install
php call cfg env -i # создать .env, если его нет
php call cfg key -g # сгенерировать свой WINTER_KEY
php call storage init # создать каталоги внутри storage/
php call run devКлюч у каждой установки свой
WINTER_KEY не переезжает из чужого проекта или из репозитория — генерируйте его на
месте. Файл .env по той же причине не коммитится.
Право на исполнение у call хранится в самом репозитории, так что chmod +x обычно не
нужен. Если файл всё же пришёл без него — например, через архив, — верните бит:
chmod +x call.
Пакеты по надобности
В ядре нет ни слоя базы данных, ни клиента Redis: они живут отдельными пакетами и ставятся, когда нужны. Ядро подхватывает их само — ничего включать не требуется.
composer require flytachi/winter-ppa # база: репозитории, сущности, миграции
composer require flytachi/winter-redis # Redis: сторы, хеши, списки, стримы
composer require flytachi/jwt # JWT и JWKSПока пакет не установлен, команды, которым он нужен, не падают со стеком, а объясняют, чего не хватает:
| [!] The 'db' command needs the database layer, which is not installed.
| [i] Add it with: composer require flytachi/winter-ppaЧто дальше — PPA, Redis, Экосистема.
Что ещё пригодится сразу
Автодополнение в терминале — подсказки по командам и их аргументам:
php call cfg completion -iКонфигурация Docker — Dockerfile, docker-compose.yml и каталог docker/ с
точкой входа под Swoole:
php call cfg dockerРежим выбирается переменной DEV, и по умолчанию она выключена:
docker compose up # рабочий режим
DEV=true docker compose up # разработка: перезапуск при изменении файловДальше
- Быстрый старт — первый маршрут за пять минут
- Структура проекта — что за что отвечает
- Состав приложения — веб, процессы, демоны, планировщик
- Конфигурация — переменные окружения