gustav-php / gustav
A modern HTTP Framework for PHP.
Requires
- php: ^8.2
- ext-fileinfo: *
- haydenpierce/class-finder: ^0.5.3
- nyholm/psr7: ^1.8
- psr/event-dispatcher: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
- spiral/roadrunner-cli: ^2.6
- spiral/roadrunner-http: ^4.1
- symfony/console: ^7.4
- symfony/dotenv: ^7.0
- symfony/process: ^7.0
Requires (Dev)
- laravel/pint: ^1.30.4
- pestphp/pest: ^3.8
- phpstan/phpstan: ^2.2.9
This package is auto-updated.
Last update: 2026-08-24 14:22:41 UTC
README
Gustav is a PHP framework for building web applications. It is designed to be simple, object-oriented and using the latest features of PHP.
Installation
Before creating your first GustavPHP project, you should ensure that your local machine has PHP and Composer installed.
After you have installed PHP and Composer, you may create a new GustavPHP project via the create-project command:
composer create-project gustav-php/starter --ask
Usage
After the project has been created, start GustavPHP's local development server using the dev command:
php gustav dev
Controllers are plain constructor-injected classes. #[Controller] supplies a
shared path prefix and concise HTTP method attributes declare handlers:
use GustavPHP\Gustav\Attribute\{Controller, Get, Param}; #[Controller('/dogs')] final readonly class DogsController { #[Get('/{dog}', name: 'dogs.show')] public function show(#[Param('dog')] int $id): DogOutput { // ... } }
Inject Router\UrlGeneratorInterface when you need to generate paths for named
routes.
Application commands are discovered from src/Commands and use typed
arguments, options, validation, and constructor injection. List every built-in
and project command with:
php gustav list
Typed event objects are dispatched through PSR-14. Invokable #[Listener]
classes under src/Events are discovered automatically and may receive
constructor dependencies.
Documentation
See CONTRIBUTING.md to work on the framework itself.
Versioning
Gustav follows Semantic Versioning from version 1.0.
Public and protected APIs that are not marked @internal, together with
documented configuration and command behavior, are covered by that promise.
Breaking changes are reserved for major releases.