horizom/core

The Horizom Core package.

Maintainers

👁 lambirou

Package info

github.com/horizom/core

Homepage

pkg:composer/horizom/core

Statistics

Installs: 371

Dependents: 1

Suggesters: 1

Stars: 1

Open Issues: 0

5.2.0 2026-04-21 21:42 UTC

MIT 6d719090561dd077836363ccb194401dfd04b5ff

  • Roland Edi <rolandedi.woop@codivoire.com>

phpcorehorizonhorizom

This package is auto-updated.

Last update: 2026-06-21 22:12:17 UTC


README

👁 Image

👁 Total Downloads
👁 Latest Stable Version
👁 License
👁 PHP Version
👁 PHPUnit

The core of the Horizom framework - a PSR-oriented PHP 8 micro-framework built around a DI container, a service provider system, a router, and a PSR-15 middleware pipeline.

Note: This repository contains the Horizom core code. To create a complete application, see the main repository horizom/app.

Table of Contents

Requirements

Dependency Minimum version
PHP 8.0
ext-mbstring *
ext-openssl *

Installation

composer require horizom/core

Quick Start

<?php

require 'vendor/autoload.php';

define('HORIZOM_ROOT', __DIR__);

use Horizom\Core\App;
use Horizom\Http\Request;

$app = new App(basePath: __DIR__);

// Register service providers
$app->register(\Horizom\Core\Providers\CoreServiceProvider::class);

// Add global middlewares
$app->add(\Horizom\Core\Middlewares\BodyParsingMiddleware::class);
$app->add(\Horizom\Core\Middlewares\ContentLengthMiddleware::class);

// Define routes through the router
$app->getRouter()->get('/', function () {
 return view('home', ['title' => 'Horizom']);
});

$app->run(Request::createFromGlobals());

Architecture

horizom/core
├── src/
│ ├── App.php # Application entry point
│ ├── Config.php # Configuration storage (Collection)
│ ├── Container.php # Extended DI container (php-di)
│ ├── ServiceProvider.php # Base provider class
│ ├── View.php # Blade adapter (illuminate/view)
│ ├── helpers.php # Utility global functions
│ ├── Contracts/ # Framework interfaces
│ │ ├── ExceptionHandler.php
│ │ ├── FacadeContract.php
│ │ └── Responsable.php
│ ├── Exceptions/
│ │ └── VersionException.php
│ ├── Facades/ # Static proxies to the container
│ │ ├── Config.php
│ │ ├── Facade.php
│ │ ├── Request.php
│ │ ├── Response.php
│ │ └── View.php
│ ├── Middlewares/ # PSR-15 middlewares
│ │ ├── BodyParsingMiddleware.php
│ │ ├── ContentLengthMiddleware.php
│ │ └── ExceptionHandlingMiddleware.php
│ └── Providers/ # Built-in providers
│ ├── ConfigServiceProvider.php
│ ├── CoreServiceProvider.php
│ ├── ExceptionServiceProvider.php
│ └── ViewServiceProvider.php
└── tests/
 └── Units/

Components

Application (App)

App is the framework's central singleton. It orchestrates the DI container, the middleware dispatcher, and the router.

use Horizom\Core\App;
use Horizom\Http\Request;

$app = new App(basePath: __DIR__);

// Singleton - retrieve the existing instance
$app = App::getInstance();

// Framework version
echo $app->version(); // "4.0.0"

Service Binding

// Simple binding
$app->bind(MyInterface::class, MyImplementation::class);

// Shared singleton
$app->singleton(CacheInterface::class, RedisCache::class);

// Already instantiated concrete instance
$app->instance(LoggerInterface::class, new FileLogger('/var/log/app.log'));

// Automatic resolution (autowiring)
$service = $app->make(MyService::class);

// Presence check
$app->has(MyInterface::class); // bool

PSR-15 Middlewares

// Add a middleware to the global pipeline
$app->add(new \Horizom\Core\Middlewares\ContentLengthMiddleware());
$app->add(MyCustomMiddleware::class); // resolved through the container

Configuration

// Read all configuration
$all = $app->config();

// Load a configuration file
// Loads config/database.php and merges the keys
$app->configure('database');

// Write one or more values
$app->config(['app.name' => 'My App', 'app.env' => 'production']);

Running

// Runs the pipeline, dispatches the request, emits the HTTP response
$app->run(Request::createFromGlobals());

Configuration (Config)

Config extends Illuminate\Support\Collection with default values merged automatically at construction time.

Default values:

Key Default value
app.name 'Horizom'
app.env 'development'
app.base_url 'http://localhost:8000'
app.timezone 'UTC'
app.locale 'en_US'
app.exception_handler false
app.display_exception false
providers []
aliases []
use Horizom\Core\Facades\Config;

// Read with a default value
$name = Config::get('app.name', 'MyApp');

// Write
Config::put('app.debug', true);

// Check whether a key exists
Config::has('app.timezone'); // true

// Read through the helper
$tz = config('app.timezone', 'UTC');

DI Container (Container)

Container extends DI\Container (php-di) by adding service provider management.

use Horizom\Core\Container;
use DI\ContainerBuilder;

$builder = new ContainerBuilder(Container::class);
$container = $builder->useAutowiring(true)->build();

// Register a provider
$provider = new MyServiceProvider($app);
$container->register($provider);

// Check whether a provider is loaded
$container->isLoaded(MyServiceProvider::class); // bool

// Retrieve a registered provider
$provider = $container->getProvider(MyServiceProvider::class);

// Boot all providers
$container->boot();

Service Providers

Service providers encapsulate feature initialization. Two methods are available: register() for DI binding and boot() for post-registration initialization.

<?php

declare(strict_types=1);

namespace App\Providers;

use Horizom\Core\ServiceProvider;

class DatabaseServiceProvider extends ServiceProvider
{
 public function register(): void
 {
 // Bind interfaces to their implementations
 $this->app->singleton(
 \App\Contracts\DatabaseInterface::class,
 \App\Services\PdoDatabase::class
 );
 }

 public function boot(): void
 {
 // Code executed after all providers have been registered
 $db = $this->app->get(\App\Contracts\DatabaseInterface::class);
 $db->connect();
 }

 public function provides(): array
 {
 return [\App\Contracts\DatabaseInterface::class];
 }
}

Registration in configuration:

// config/app.php (or via App::config())
return [
 'providers' => [
 App\Providers\DatabaseServiceProvider::class,
 ],
];

Default providers:

Provider Role
CoreServiceProvider Defines the HORIZOM_* constants
ExceptionServiceProvider Configures exception handling (Ignition)
ViewServiceProvider Initializes the Blade template engine

Facades

Facades provide convenient static access to container services without tight coupling.

use Horizom\Core\Facades\Config;
use Horizom\Core\Facades\Request;
use Horizom\Core\Facades\Response;
use Horizom\Core\Facades\View;

// Config
$locale = Config::get('app.locale');

// Request
$email = Request::input('email');
$token = Request::bearerToken();

// Response
return Response::json(['status' => 'ok']);
return Response::redirect('/dashboard', 302);

// View
$html = View::render('emails.welcome', ['user' => $user]);

Creating a Custom Facade

<?php

declare(strict_types=1);

namespace App\Facades;

use Horizom\Core\Facades\Facade;

class Cache extends Facade
{
 public static function getFacadeAccessor(): string
 {
 return \App\Services\CacheService::class;
 }
}

Middlewares

All middlewares implement Psr\Http\Server\MiddlewareInterface.

BodyParsingMiddleware

Automatically parses the request body according to Content-Type.

Content-Type Result
application/json array
application/x-www-form-urlencoded array
application/xml / text/xml SimpleXMLElement
use Horizom\Core\Middlewares\BodyParsingMiddleware;

$middleware = new BodyParsingMiddleware();

// Register a custom parser
$middleware->registerBodyParser('application/msgpack', function (string $body): array {
 return msgpack_unpack($body);
});

$app->add($middleware);

ContentLengthMiddleware

Automatically adds the Content-Length header if it is missing.

$app->add(new \Horizom\Core\Middlewares\ContentLengthMiddleware());

ExceptionHandlingMiddleware

Delegates unhandled exceptions to an ExceptionHandler injected through DI.

use Horizom\Core\Contracts\ExceptionHandler;
use Horizom\Core\Middlewares\ExceptionHandlingMiddleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

class MyExceptionHandler implements ExceptionHandler
{
 public function handle(
 \Throwable $e,
 ServerRequestInterface $request,
 RequestHandlerInterface $handler
 ): ResponseInterface {
 // Build a custom error response
 }
}

$app->instance(ExceptionHandler::class, new MyExceptionHandler());
$app->add(new ExceptionHandlingMiddleware($app->get(ExceptionHandler::class)));

Blade View (View)

Adapter around illuminate/view to use the Blade template engine without Laravel.

use Horizom\Core\View;

$view = new View(
 viewPaths: [__DIR__ . '/resources/views'],
 cachePath: __DIR__ . '/storage/cache/views',
);

// Render a view
echo $view->render('welcome', ['name' => 'Alice']);

// Custom directive
$view->directive('datetime', fn($expr) => "<?php echo ($expr)->format('d/m/Y H:i'); ?>");

// Share global data
$view->share('appName', config('app.name'));

Through the global helper:

// In a route handler
return view('dashboard', ['user' => $user]);

Through the facade:

use Horizom\Core\Facades\View;

$html = View::render('emails.confirmation', compact('order'));

Helpers

Global functions available throughout the application.

Function Description
app() Returns the App instance
config($key, $def) Reads a configuration value
url($path) Generates an absolute URL
asset($path) Generates the URL for a public asset
view($name, $data) Renders a view and writes it to output
bcrypt($value) Hashes a value with Bcrypt
base_path($path) Absolute path from the project root
storage_path($path) Path to storage/
public_path($path) Path to public/
resources_path($path) Path to resources/
$url = url('users/profile'); // http://localhost:8000/users/profile
$asset = asset('css/app.css'); // http://localhost:8000/css/app.css
$storage = storage_path('logs/app.log'); // /path/to/project/storage/logs/app.log
$hash = bcrypt('my-secret-password');

Tests

# Run the test suite
vendor/bin/phpunit

# With detailed output
vendor/bin/phpunit --testdox

# With code coverage (requires Xdebug)
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html coverage

The suite covers:

Class Test cases
Config Default values, merging, read/write/exists
Container Registration, force-register, boot, isLoaded
ServiceProvider provides, when, register, boot, defaultProviders
VersionException Default message, code, \Throwable chaining
BodyParsingMiddleware JSON, form-encoded, unknown type, custom parser
ContentLengthMiddleware Header injection, no overwrite when already present
ExceptionHandlingMiddleware Pass-through, delegation, request context propagation

License

Horizom Core is open-source software released under the MIT license.