Introduction

What is Winter

Winter is a PHP framework for APIs and web applications. Routes, parameter binding, validation and database work are declared with attributes, right in the code — no configuration files, no registries, no generated magic. And the application stays resident, serving requests on coroutines.

Language PHP 8.4+Runtime SwooleScope APIs · web · background services

Who this is for

What the code looks like

A controller is a class extending the Controller stereotype; a route is an attribute on a method. Nothing else needs registering:

main/MainController.php
<?php

namespace Main;

use Flytachi\Winter\Kernel\Http\Response\ResponseEntity;
use Flytachi\Winter\Kernel\Http\Stereotype\Controller;
use Flytachi\Winter\Kernel\Route\Annotation\GetMapping;

class MainController extends Controller
{
  #[GetMapping]
  public function index(): ResponseEntity
  {
      return ResponseEntity::ok('Hello, Winter');
  }
}

That is already a working GET / route. The full walkthrough is in the Quick start.

Three principles

Briefly here, at length in the Philosophy.

Explicit beats implicit. Behaviour lives in the same file as the code it governs: an attribute on a method is the route. Nothing hides in a config file you have to remember to update when you rename something.

CLI instead of boilerplate. call make creates components, call mapping show prints the routes, call cfg prepares the environment. There is no scaffolding to copy by hand.

Performance by default. The application boots once and stays in memory; the expensive work — scanning the project, building the container, compiling the route table — happens before the first request rather than on every one.

Coming from Laravel or Symfony?

The concepts carry over — controllers, DI, middleware, repositories — so the code reads at a glance. Two differences are worth noticing immediately: the application does not die after a request, and a service is transient by default, not a singleton. Both are covered in Key concepts.

What it does

Capability What it looks like
Routing #[GetMapping], #[PostMapping] on methods; the table builds itself
Request binding #[PathVariable], #[RequestQuery], #[RequestJson], #[RequestForm], #[RequestFile]
Validation #[Valid] plus 24 constraints: #[NotBlank], #[Size], #[Email], #[Uuid]
Database (PPA) Repositories and entities on attributes, a query builder, migrations from code
Container Autowiring with no registration, three scopes, scope conflicts caught at boot
Background work Processes, supervised daemon fleets, #[Scheduled], parallel #[Async] calls
Console (call) Generators, your own commands, the server, shell completion
Observability Channel-based logging, /actuator health endpoints

What makes Winter different

Three decisions shape how it feels to work with:

The application is resident. Classic PHP builds its world on every request and tears it down afterwards. Winter starts once and serves requests on coroutines: while one waits on the database, the worker runs another. That is where the speed comes from — and where the new rules about state come from too.

Nothing is registered. At boot the framework walks the project and finds controllers, configurations and processes by itself. Write a class and it works. There are no lists to remember to extend.

The web layer is optional. The same code and the same container run an application with no HTTP at all: a scheduler, a queue, a set of console commands. What the application consists of is decided by one attribute on its entry class.

Where to start

bash
mkdir my-app && cd my-app
composer require flytachi/winter-kernel

From there it is a few steps to a running server: