PHP-SF is a custom PHP framework built for Nations Original — a browser-based online RTS game. It was built on top of Symfony 7, not as a replacement, but as a performance-focused layer on top of it, handling routing, middleware, views, and caching in a way that better fits the game's needs.
Symfony is a solid foundation but comes with overhead that matters at scale — router initialization, dependency injection container resolution, and templating all add up. For a game backend serving many concurrent players, that overhead is material.
PHP-SF was built to solve three specific problems:
show() methods, no Twig compilation overhead, and a clear component import chainEverything else — console commands, database migrations, Messenger workers, the web profiler, Twig where needed — stays in Symfony and is used as-is. No reinventing wheels.
Every request goes through public/index.php, which boots the PHP-SF kernel first:
Request
└── PHP_SF\System\Kernel (boots)
└── Router::init()
├── Route found → controller → response → exit
└── No route found → falls through to Symfony
├── Symfony route found → normal Symfony response
└── No route found → Symfony 404
This means you can use both framework controllers and standard Symfony controllers in the same project, and the framework never blocks Symfony from doing its job. See Symfony Fallback for details.
| Concept | What it does |
|---|---|
| Routing | PHP 8 attribute-based routes with URL params, HTTP methods, and middleware |
| Middleware | MiddlewareAll, MiddlewareAny, MiddlewareCustom — composable auth/access logic |
| Controllers | Extend AbstractController, return Response, JsonResponse, or RedirectResponse |
| Views | PHP class templates, explicit rendering, component imports, layout system |
| Cache | Unified adapter for Redis, APCu, and Memcached behind ca(), rca(), aca() |
| Entities | Doctrine ORM entities with built-in validation constraints and lifecycle callbacks |
# Clone the template project
git clone https://github.com/Ondottr/PHP_SF_template
# Run the interactive installer
chmod +x install.sh && ./install.sh
# Start the dev server
chmod +x run.sh && ./run.sh
The installer walks you through .env configuration, config/constants.php, database setup, and fixture loading. See Installation & Setup for a full walkthrough.
├── App/ # Your application code
│ ├── Entity/ # Doctrine entities
│ ├── Http/
│ │ ├── Controller/ # Framework controllers
│ │ ├── Middleware/ # Custom middleware
│ │ └── SymfonyControllers/ # Pure Symfony controllers
│ ├── Repository/ # Entity repositories
│ ├── Enums/ # Application enums
│ ├── DataFixtures/ # Database fixtures
│ └── Command/ # Symfony console commands
├── config/ # Symfony + framework config
│ └── constants.php # Framework constants (not committed)
├── templates/ # PHP-SF view classes
├── templates_twig/ # Twig templates (Symfony fallback)
├── functions/ # Global helper functions
├── public/
│ └── index.php # Entry point
└── tests/ # PHPUnit + Codeception tests
The project runs two kernels simultaneously — PHP_SF\System\Kernel (the framework) and App\Kernel (Symfony). This is intentional and explained in detail in Dual Kernel Architecture. The short version: the framework kernel handles requests, the Symfony kernel handles everything else.
If you're setting up a new project → Installation & Setup
If you want to understand how a request works → Request & Response Lifecycle
If you're jumping straight into code → Routing