CLI · Winter Console

Команда di

При старте фреймворк обходит проект и находит классы — это самая дорогая часть запуска. di управляет кешем этого обхода: собирает его заранее, показывает содержимое и удаляет. Он же собирает прокси для #[Async].

Действия build · clean · show · asyncКеш во временном каталоге системыDEBUG=true кеш выключен

Зачем

Обход проекта читает каждый .php и подключает те, где объявлен класс. На среднем проекте это десятки миллисекунд и лишние мегабайты в памяти мастер-процесса — из которого потом форкаются все воркеры.

di build делает эту работу один раз, заранее, и складывает результат в файл. Приложение при старте читает готовый список вместо обхода диска.

Действия

Действие Что делает
build Обходит проект один раз: пишет кеш, генерирует прокси #[Async], проверяет корректность
clean Удаляет кеш и все сгенерированные прокси
show [шаблон] Печатает классы из кеша; шаблон фильтрует по подстроке FQCN
async [шаблон] Печатает методы #[Async] и собран ли для них прокси
bash
php call di build
php call di clean
php call di show
php call di show Repository     # только содержащие "Repository"
php call di async

build перед запуском

Основной сценарий — прогрев в контейнере, до старта приложения. Именно так устроен образ, который создаёт cfg docker:

sh
if ! su-exec winter php /var/www/html/call di build; then
  echo "entrypoint: 'call di build' failed — refusing to start" >&2
  exit 1
fi
exec su-exec winter php /var/www/html/call run --port="$PORT"

`build` — ещё и проверка

Команда не просто складывает список: она разбирает каждый метод #[Async] и генерирует для него прокси. Метод, который так проксировать нельзя, роняет сборку — здесь, с понятным сообщением и кодом выхода 1, а не в проде на первом вызове.

Поэтому её и ставят в entrypoint перед запуском: сломанное приложение даёт одну внятную строку в docker logs вместо контейнера, падающего по кругу.

Дополнительно build предупреждает, когда класс с методами #[Async] создаётся через new — прокси тогда не применится. Проверка текстовая, new $class и фабрики она не видит, поэтому это именно предупреждение: сборку оно не роняет.

Где лежит кеш

По умолчанию — во временном каталоге системы, а не в проекте:

text
/tmp/flytachi.winter.volatile.<имя-проекта>/di.php      список классов
/tmp/flytachi.winter.volatile.<имя-проекта>/async/     прокси #[Async]

Точные пути показывает php call help di. Сгенерированный код не попадает в образ и не переживает перезагрузку машины — это осознанный выбор.

Практическое следствие: чистить storage/ для сброса кеша бесполезно, для этого есть di clean.

При `DEBUG=true` кеш не используется вовсе

В режиме разработки приложение обходит проект на каждом старте, чтобы новый класс подхватывался без ручной пересборки. Собранный di build в этом режиме просто игнорируется.

Если после di build изменения «не видны» — первым делом проверьте DEBUG.

show без кеша

Если кеша нет, show не падает: он выполняет живой обход, печатает результат и предупреждает, что показанное на диск не записано. Так команда остаётся полезной и в разработке.

async

bash
php call di async

Показывает все методы, помеченные #[Async], и состояние прокси для каждого. Это способ ответить на вопрос «почему метод выполняется синхронно»: если прокси не собран, вызов идёт напрямую.

Дальше