The lightness PHP framework — fast, minimal, PSR-compliant.
Horizom is a lightweight PHP micro-framework built on PSR standards. It provides a clean, expressive foundation for building web applications and REST APIs without the overhead of a full-stack framework.
Core packages:
| Package | Role |
|---|---|
horizom/core |
Application container, configuration, lifecycle |
horizom/routing |
PSR-15 router powered by FastRoute |
horizom/http |
PSR-7 request/response helpers |
- PHP 8.0 or higher
- Composer 2.x
composer create-project horizom/app my-project
cd my-project
cp .env.example .envStart the built-in development server:
composer serve
# → http://localhost:8000├── app/
│ ├── Controllers/ # Request handlers (PSR-7)
│ ├── Middlewares/ # PSR-15 middleware (CORS, errors…)
│ ├── Models/ # Domain models
│ └── Providers/ # Service providers
├── bootstrap/
│ ├── app.php # Application bootstrap
│ └── dependencies.php # Middleware registration
├── config/
│ ├── app.php # App settings
│ ├── auth.php # JWT / auth settings
│ └── database.php # Database connections
├── public/
│ └── index.php # Front controller
├── resources/
│ └── views/ # Blade templates
├── routes/
│ ├── web.php # Web routes
│ └── api.php # API routes
└── tests/
└── Unit/ # PHPUnit test suites
All sensitive values must be set in your .env file and are never committed to version control.
# Application
APP_NAME=Horizom
APP_ENV=development
APP_URL=http://localhost:8000
APP_DEBUG=false
# Database
DB_DRIVER=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=horizom
DB_USERNAME=root
DB_PASSWORD=Access config values anywhere with the config() helper:
$name = config('app.name'); // "Horizom"
$dsn = config('database.default'); // "development"$router->get('/', 'MainController@index');$router->group(['prefix' => 'api'], function (RouteCollector $router) {
$router->get('/status', 'ApiController@status');
$router->get('/version', 'ApiController@version');
});Use explicit HTTP verbs — avoid any() as it widens the attack surface.
Controllers are final classes. They return a PSR-7 ResponseInterface.
<?php
declare(strict_types=1);
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface;
final class ApiController
{
public function status(): ResponseInterface
{
return response()->json(['status' => 'UP']);
}
}Global middleware is registered in bootstrap/dependencies.php:
$app->add(new \App\Middlewares\CorsMiddleware());Handles preflight OPTIONS requests directly — returns 204 without invoking the next handler — and attaches CORS headers to all other responses.
To restrict allowed origins in production, edit the $allowedOrigins property:
// app/Middlewares/CorsMiddleware.php
private array $allowedOrigins = [
'https://myapp.com',
'https://www.myapp.com',
];Maps exceptions to structured HTTP responses:
| Exception | Status |
|---|---|
NotFoundException |
404 Not Found |
MethodNotAllowedException |
405 Method Not Allowed |
Any other Throwable |
500 Internal Server Error |
XHR / AJAX requests receive a JSON payload; browser requests receive an HTML error page.
Stack traces are only included when
app.pretty_debug = true. Never expose them in production.
| Method | Path | Description |
|---|---|---|
GET |
/api |
Health check alias |
GET |
/api/status |
Returns { "status": "UP" } |
GET |
/api/version |
Returns the framework version |
Templates use the Blade engine. Layouts live in resources/views/.
@extends('default')
@section('content')
<h1>Hello, World!</h1>
@endsectionAvailable helpers inside templates:
{{ config('app.name') }}
{{ asset('css/style.css') }}Tests use PHPUnit 11 and live in tests/Unit/.
composer test
# or directly:
vendor/bin/phpunittests/
└── Unit/
├── Controllers/
│ └── ApiControllerTest.php
└── Middlewares/
├── CorsMiddlewareTest.php
└── ErrorHandlerMiddlewareTest.php
| Concern | Mitigation |
|---|---|
| Secrets in source code | Use .env for all credentials — never hardcode |
| Stack trace exposure | Only shown when app.pretty_debug = true |
| CORS wildcard in production | Replace ['*'] with an explicit origin list |
| Over-broad HTTP verbs | API routes use GET only; avoid any() |
| Type safety | All classes declare strict_types=1 |
The full Horizom documentation covers installation, routing, middleware, templating, and more.
The Horizom framework is open-sourced software licensed under the MIT license.