PHPackages                             luany/framework - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. luany/framework

ActiveLibrary[Framework](/categories/framework)

luany/framework
===============

Luany Framework — Compiler-grade PHP MVC framework. Integrates luany/core and luany/lte.

v1.0.2(3mo ago)036↓76.9%1MITPHPPHP &gt;=8.2CI passing

Since Feb 25Pushed 3mo agoCompare

[ Source](https://github.com/luany-ecosystem/luany-framework)[ Packagist](https://packagist.org/packages/luany/framework)[ Docs](https://github.com/luany-ecosystem/luany-framework)[ RSS](/packages/luany-framework/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (16)Versions (13)Used By (1)

luany/framework
===============

[](#luanyframework)

**Application framework for Luany. IoC container, HTTP kernel, sessions, validation, config, CSRF, i18n.**

**Version**: v1.0.0 | **PHP**: &gt;= 8.2 | **License**: MIT **Author**: António Ambrósio Ngola | **Org**: [luany-ecosystem](https://github.com/luany-ecosystem)

---

Table of Contents
-----------------

[](#table-of-contents)

1. [Overview](#1-overview)
2. [Installation](#2-installation)
3. [Application Container](#3-application-container)
4. [HTTP Kernel](#4-http-kernel)
5. [Config](#5-config)
6. [Session](#6-session)
7. [Validation](#7-validation)
8. [CSRF Protection](#8-csrf-protection)
9. [Exception Handling](#9-exception-handling)
10. [Helpers](#10-helpers)
11. [Service Providers](#11-service-providers)
12. [Changelog](#12-changelog)

---

1. Overview
-----------

[](#1-overview)

`luany/framework` is the application layer of the Luany ecosystem. It wires together the IoC container, HTTP lifecycle, session management, validation, configuration, and i18n into a coherent application runtime.

It depends on `luany/core` for routing, request and response primitives, and on `luany/lte` for the template engine.

---

2. Installation
---------------

[](#2-installation)

```
composer require luany/framework
```

The framework is typically used through the application skeleton (`luany/luany`), which already configures everything correctly.

---

3. Application Container
------------------------

[](#3-application-container)

The `Application` class is the IoC container and global registry.

```
use Luany\Framework\Application;

$app = new Application(__DIR__); // pass the application root path

// Bind a factory (new instance every call)
$app->bind('mailer', fn($app) => new Mailer(env('MAIL_HOST')));

// Bind a singleton (resolved once, cached)
$app->singleton('cache', fn($app) => new Cache(env('CACHE_DRIVER')));

// Store a pre-built instance
$app->instance('db', $existingConnection);

// Resolve from the container
$cache = $app->make('cache');
$cache = app('cache'); // via helper
```

The `Application` instance is accessible globally via `app()`.

### Auto-resolution

[](#auto-resolution)

Classes with no constructor dependencies are auto-resolved:

```
$handler = $app->make(SomeHandler::class);
```

### Service Provider lifecycle

[](#service-provider-lifecycle)

```
$app->register(new DatabaseServiceProvider());
// register() calls provider->register() immediately
// boot() is deferred until $app->bootProviders() (called by Kernel)
```

### Path helpers

[](#path-helpers)

```
$app->basePath()             // /var/www/my-app
$app->basePath('config')     // /var/www/my-app/config
$app->configPath()           // /var/www/my-app/config
$app->storagePath('logs')    // /var/www/my-app/storage/logs
$app->cachePath('views')     // /var/www/my-app/storage/cache/views
$app->viewsPath()            // /var/www/my-app/views
$app->routesPath()           // /var/www/my-app/routes
```

---

4. HTTP Kernel
--------------

[](#4-http-kernel)

The Kernel orchestrates the full HTTP request lifecycle.

```
// public/index.php
$app    = new Application(__DIR__ . '/..');
$kernel = $app->make(Kernel::class);
$kernel->boot();
$request  = Request::fromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
```

### Boot sequence

[](#boot-sequence)

`boot()` runs in order:

1. `registerConfig()` — loads `config/*.php`
2. `registerSession()` — starts `FileSession`
3. `registerCsrf()` — binds `CsrfToken`
4. `registerLte()` — binds the LTE view engine
5. `loadRoutes()` — requires `routes/http.php`
6. `bootProviders()` — calls `boot()` on all registered providers

### Global middleware

[](#global-middleware)

Override in your application kernel:

```
// app/Http/Kernel.php
class Kernel extends \Luany\Framework\Http\Kernel
{
    protected array $middleware = [
        LocaleMiddleware::class,
        CsrfMiddleware::class,
    ];
}
```

Middleware runs on every request, before routing.

---

5. Config
---------

[](#5-config)

Loads PHP files from `config/` and provides dot-notation access.

```
// config/app.php
return ['name' => 'My App', 'debug' => false];

// Usage
config('app.name')           // 'My App'
config('app.missing', 'def') // 'def'
config('app.debug')          // false
```

Direct usage:

```
$config = app('config');
$config->get('app.name');
$config->set('app.debug', true);  // runtime override
$config->has('app.name');         // true
$config->all();                   // full array
```

---

6. Session
----------

[](#6-session)

Cookie-based sessions backed by the filesystem (file-per-session in `storage/sessions/`).

```
// Via helper
session()                    // SessionInterface instance
session('user_id')           // get value
session('user_id', 0)        // get with fallback

// Via instance
$session = app('session');
$session->set('user_id', 42);
$session->get('user_id');
$session->has('user_id');
$session->forget('user_id');
$session->flash('success', 'Saved!');   // lives for one request
$session->regenerate();                  // new session ID
$session->destroy();
```

Flash data is available on the next request only:

```
// In controller
session()->flash('success', 'Record saved.');

// In view (next request)
{{ session('success') }}
```

Old input is automatically available via `old()` after a failed `validate()`:

```

```

---

7. Validation
-------------

[](#7-validation)

### Validator directly

[](#validator-directly)

```
use Luany\Framework\Validation\Validator;

$v = Validator::make($request->body(), [
    'name'     => 'required|string|min:2|max:255',
    'email'    => 'required|email|unique:users,email',
    'password' => 'required|string|min:8|confirmed',
    'role'     => 'required|in:admin,editor,viewer',
]);

if ($v->fails()) {
    $errors = $v->errors();    // ['name' => ['The name field is required.']]
}

$data = $v->validated();       // only validated fields
```

### validate() helper — recommended

[](#validate-helper--recommended)

The `validate()` helper removes all boilerplate from controllers. On failure it automatically flashes errors and old input to the session, then throws a `ValidationException` which the Kernel resolves as a redirect.

```
public function store(Request $request): Response
{
    $data = validate($request->body(), [
        'name'  => 'required|string|min:2|max:255',
        'email' => 'required|email',
    ], '/users/create');   // redirect URL on failure

    User::create($data);
    return redirect('/users');
}
```

On failure the user is redirected to `/users/create` with errors and old input in session. The third argument defaults to `$_SERVER['HTTP_REFERER']` if omitted.

In the view:

```
@ifempty(session('errors'))
    {{-- no errors --}}
@else
    @foreach(session('errors') as $field => $messages)
        @foreach($messages as $message)
            {{ $message }}
        @endforeach
    @endforeach
@endisset
```

### Available rules

[](#available-rules)

RuleDescription`required`Field must be present and non-empty`string`Must be a string`email`Must be a valid email address`numeric`Must be numeric`min:N`Minimum length (string) or value (numeric)`max:N`Maximum length (string) or value (numeric)`in:a,b,c`Must be one of the listed values`confirmed`Must match `{field}_confirmation``unique:table,col`Must not already exist (requires `setUniqueChecker`)### unique rule with database

[](#unique-rule-with-database)

```
Validator::setUniqueChecker(function (string $table, string $column, mixed $value): bool {
    return (bool) app('db')->table($table)->where($column, $value)->exists();
});
```

---

8. CSRF Protection
------------------

[](#8-csrf-protection)

`CsrfToken` generates and validates tokens stored in the session.

```
$csrf = app('csrf');
$token = $csrf->token();    // get or generate token
$csrf->validate($token);    // throws if invalid
```

In LTE templates, use `@csrf`:

```

    @csrf
    ...

```

The `CsrfMiddleware` automatically validates tokens on `POST`, `PUT`, `PATCH`, `DELETE` requests. It skips validation for `GET`, `HEAD`, `OPTIONS`.

---

9. Exception Handling
---------------------

[](#9-exception-handling)

### abort()

[](#abort)

Abort the current request with an HTTP status code:

```
abort(404);
abort(403, 'Forbidden');
abort(422, 'Unprocessable content');
```

Throws `HttpException` which the Kernel converts to the appropriate response.

### Custom handler

[](#custom-handler)

```
// app/Exceptions/Handler.php
class Handler extends \Luany\Framework\Exceptions\Handler
{
    public function render(\Throwable $e): Response
    {
        if ($e instanceof SomeCustomException) {
            return Response::make(view('errors.custom'), 400);
        }
        return parent::render($e);
    }
}
```

Register in a service provider:

```
$app->singleton(\Luany\Framework\Exceptions\Handler::class, fn() => new Handler(
    debug: (bool) env('APP_DEBUG', false)
));
```

### Exception priority in Kernel

[](#exception-priority-in-kernel)

1. `ValidationException` → flash is already done → redirect to `$e->getRedirectTo()`
2. `HttpException` → `Response::make($message, $statusCode)`
3. `RouteNotFoundException` → `Response::notFound()`
4. Everything else → custom `Handler::render()` or `Response::serverError()`

---

10. Helpers
-----------

[](#10-helpers)

All helpers are in `src/Support/helpers.php` and auto-loaded via Composer.

HelperDescription`app(?string $abstract)`Resolve from container`env(string $key, mixed $default)`Get environment variable`base_path(string $path)`Absolute path from app root`view(string $name, array $data)`Render a view via LTE`redirect(string $url, int $status)`Create redirect Response`response(string $body, int $status)`Create Response`config(string $key, mixed $default)`Get config value`session(?string $key, mixed $default)`Get session or value`csrf_token()`Get current CSRF token`old(string $key, mixed $default)`Get previous request input`validate(array $data, array $rules, string $back)`Validate or throw`abort(int $code, string $message)`Abort with HTTP error`__(string $key, array $replace)`Translate a key`locale()`Get current locale---

11. Service Providers
---------------------

[](#11-service-providers)

Service providers are the recommended way to register application bindings.

```
use Luany\Framework\ServiceProvider;
use Luany\Framework\Contracts\ApplicationInterface;

class DatabaseServiceProvider extends ServiceProvider
{
    public function register(ApplicationInterface $app): void
    {
        $app->singleton('db', fn() => new Connection(
            host:     env('DB_HOST', '127.0.0.1'),
            database: env('DB_NAME', 'luany'),
            username: env('DB_USER', 'root'),
            password: env('DB_PASS', ''),
        ));
    }

    public function boot(ApplicationInterface $app): void
    {
        // Called after all providers are registered
        // Safe to resolve other bindings here
    }
}
```

Register in `bootstrap/app.php`:

```
$app->register(new DatabaseServiceProvider());
```

**Total: OK (174 tests, 223 assertions)**
-----------------------------------------

[](#total-ok-174-tests-223-assertions)

12. Changelog
-------------

[](#12-changelog)

### next/v1 — Phase 6

[](#nextv1--phase-6)

**New:**

- `src/Exceptions/HttpException.php` — thrown by `abort()`, carries status code and message
- `src/Exceptions/ValidationException.php` — thrown by `validate()` on failure, carries errors + redirect URL
- `helpers.php` — added `abort(int $code, string $message = ''): never`
- `helpers.php` — added `validate(array $data, array $rules, string $back = ''): array`

**Modified:**

- `src/Http/Kernel.php` — `handleException()` handles `ValidationException` and `HttpException` before custom handler

### v0.4.0 — Phase 2

[](#v040--phase-2)

IoC container (`Application`), HTTP Kernel, `FileSession`, `Config`, `CsrfToken`, `CsrfMiddleware`, `Validator` (9 rules), `Translator`, `LocaleMiddleware`. Full `helpers.php`: `app()`, `env()`, `base_path()`, `view()`, `redirect()`, `response()`, `config()`, `session()`, `csrf_token()`, `old()`, `__()`, `locale()`.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance81

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 96.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

10

Last Release

102d ago

Major Versions

v0.4.0 → v1.0.02026-03-23

PHP version history (2 changes)v0.1.0PHP &gt;=8.1

v1.0.0PHP &gt;=8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/192051935?v=4)[António Ngola - \*\*Software Engineer\*\*](/maintainers/Ngola-Programador-Full-Stack)[@Ngola-Programador-Full-Stack](https://github.com/Ngola-Programador-Full-Stack)

---

Top Contributors

[![antoniongoladev-design](https://avatars.githubusercontent.com/u/264429300?v=4)](https://github.com/antoniongoladev-design "antoniongoladev-design (25 commits)")[![Ngola-Programador-Full-Stack](https://avatars.githubusercontent.com/u/192051935?v=4)](https://github.com/Ngola-Programador-Full-Stack "Ngola-Programador-Full-Stack (1 commits)")

---

Tags

phpframeworkmvccompilerastluany

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/luany-framework/health.svg)

```
[![Health](https://phpackages.com/badges/luany-framework/health.svg)](https://phpackages.com/packages/luany-framework)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.0k](/packages/laravel-framework)[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k15](/packages/tempest-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
