solophp / application
Application bootstrap with PSR-15 middleware pipeline
Installs: 72
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/solophp/application
Requires
- php: ^8.2
- psr/container: ^2.0
- psr/http-factory: ^1.0
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- solophp/contracts: ^1.0
Requires (Dev)
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^12.0
- solophp/container: ^2.1
- squizlabs/php_codesniffer: ^4.0
Suggests
- nyholm/psr7: PSR-7/PSR-17 implementation
- nyholm/psr7-server: ServerRequest creator from globals
- solophp/container: Default container implementation
- solophp/http-emitter: Default HTTP emitter implementation
- solophp/router: Default router implementation
README
Application bootstrap with PSR-15 middleware pipeline.
A lightweight, PSR-compliant application kernel that wires together your container, router, middleware, and HTTP layer with zero configuration overhead.
Features
- PSR-15 middleware pipeline
- PSR-11 container integration
- Service providers for dependency registration
- Flexible route handlers (controllers, invokables, callables)
- Zero framework lock-in — uses only PSR interfaces
Installation
composer require solophp/application
Requirements
- PHP 8.2+
- PSR-7 implementation (e.g., nyholm/psr7)
- PSR-11 compatible container with
set()method
Dependencies
The package depends only on PSR interfaces and solophp/contracts:
| Dependency | Purpose |
|---|---|
| psr/container | Container interface |
| psr/http-message | HTTP messages |
| psr/http-server-handler | Request handler |
| psr/http-server-middleware | Middleware |
| psr/http-factory | Response factory |
| solophp/contracts | WritableContainerInterface, EmitterInterface, RouterInterface |
Usage
// public/index.php <?php require __DIR__ . '/../vendor/autoload.php'; use Solo\Application\Application; use Solo\Application\Config; use Solo\Dotenv\Dotenv; $basePath = dirname(__DIR__); Dotenv::load($basePath, ['.env', '.env.local']); $config = new Config( basePath: $basePath, routesPath: $basePath . '/app/routes.php', providers: require $basePath . '/app/providers.php', middleware: require $basePath . '/app/middleware.php', ); $app = new Application($config); $app->run();
Required Services
Your application must register these services via providers:
| Service | Interface |
|---|---|
| Response Factory | Psr\Http\Message\ResponseFactoryInterface |
| Server Request | Psr\Http\Message\ServerRequestInterface |
| Router | Solo\Contracts\Router\RouterInterface |
| Emitter | Solo\Contracts\Http\EmitterInterface |
Example provider:
<?php namespace App\Providers; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7Server\ServerRequestCreator; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ServerRequestInterface; use Solo\Container\Container; use Solo\Contracts\Http\EmitterInterface; use Solo\Contracts\Router\RouterInterface; use Solo\HttpEmitter\Emitter; use Solo\Router\RouteCollector; final class HttpServiceProvider { public function register(Container $container): void { $container->set(Psr17Factory::class, fn() => new Psr17Factory()); $container->set(ResponseFactoryInterface::class, fn(ContainerInterface $c) => $c->get(Psr17Factory::class) ); $container->set(ServerRequestInterface::class, function (ContainerInterface $c) { $factory = $c->get(Psr17Factory::class); return (new ServerRequestCreator($factory, $factory, $factory, $factory)) ->fromGlobals(); }); $container->set(RouterInterface::class, fn() => new RouteCollector()); $container->set(EmitterInterface::class, fn() => new Emitter()); } }
Custom Container
You can provide your own container:
$container = new MyContainer(); // ... configure container ... $app = new Application($config, $container);
The container must implement Solo\Contracts\Container\WritableContainerInterface.
Components
| Class | Description |
|---|---|
Application |
Bootstrap and run the application |
Config |
Configuration DTO |
MiddlewarePipeline |
PSR-15 middleware pipeline |
RouteDispatcher |
Controller invocation |
Request Flow
HTTP Request
│
▼
Application.run()
│
▼
MiddlewarePipeline
│
▼
[Middleware 1] → [Middleware 2] → ... → [RoutingMiddleware]
│
▼
RouteDispatcher → Controller
│
▼
HTTP Response
Configuration
providers.php
<?php return [ HttpServiceProvider::class, DatabaseServiceProvider::class, LoggingServiceProvider::class, ];
middleware.php
<?php return [ CorsMiddleware::class, ErrorHandlerMiddleware::class, JsonParserMiddleware::class, RoutingMiddleware::class, ];
routes.php
<?php use Solo\Contracts\Router\RouterInterface; return function (RouterInterface $r) { $r->addRoute('GET', '/api/users', [UserController::class, 'index']); $r->addRoute('POST', '/api/users', [UserController::class, 'store']); };
Service Providers
Service providers register dependencies in the container:
<?php namespace App\Providers; use Solo\Container\Container; final class DatabaseServiceProvider { public function register(Container $container): void { $container->set(Connection::class, function () { return new Connection(/* ... */); }); } }
License
The MIT License (MIT). Please see License File for more information.