PHPackages                             heraldoffire/monad - 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. heraldoffire/monad

ActiveProject[Framework](/categories/framework)

heraldoffire/monad
==================

A single-file PHP micro-framework.

11↑2900%1PHP

Since Jul 1Pushed todayCompare

[ Source](https://github.com/HeraldOfFire/monad)[ Packagist](https://packagist.org/packages/heraldoffire/monad)[ RSS](/packages/heraldoffire-monad/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

Monad
=====

[](#monad)

Monad is an experimental, ultra-lightweight PHP micro-framework contained in a single `index.php`. It leverages metaprogramming and PHP magic methods to offer an extremely smooth development experience, focused on modern Server-Side Rendering (SSR) and natively integrated with HTMX.

Philosophy
----------

[](#philosophy)

- **Monofile Core**: The entire framework engine resides in `index.php`.
- **Zero Dependencies**: Works standalone. If you use Composer, `vendor/autoload.php` is automatically detected and integrated.
- **HTMX First**: Intelligent layout and HTMX header management to build Single Page Applications (SPA) writing only PHP and HTML.
- **Fluent &amp; Recursive View Context**: Security first with a modern twist. Views are recursive objects that provide fluent helpers and automatic XSS protection.
- **Onion Middleware**: A recursive middleware system that allows processing requests both "on the way in" and "on the way out".
- **MagicObject**: The heart of Monad. It allows defining dynamic behaviors and lazy-loading with a clean and expressive syntax.

---

Who is Monad for?
-----------------

[](#who-is-monad-for)

Monad is an experimental framework. It is perfect for:

- **Rapid Prototyping**: Build APIs or SSR web apps in minutes without configuring complex build steps or downloading massive vendor directories.
- **HTMX Enthusiasts**: If you love the hypermedia-driven approach, Monad gives you a backend that respects it perfectly, rather than fighting against JS-centric paradigms.
- **Educational Purposes**: An excellent way to study PHP metaprogramming, closures, magic methods, and Dependency Injection containers under the hood.
- **Micro-Apps &amp; Hackathons**: When you just need a robust router, a fast query builder, and a clean template engine, all in one file.

It is **NOT** recommended for massive enterprise monoliths where strict static typing across thousands of files is necessary, as its reliance on `MagicObject` trades static analysis for extreme dynamic flexibility.

---

Quickstart
----------

[](#quickstart)

Monad requires **PHP 8.0+** and **PDO extension**.

1. Clone the repository or copy `index.php`.
2. Start the PHP development server: ```
    php -S localhost:8000 -t .
    ```
3. Optional: configure your database in the `monad.ini` file.

---

The `MagicObject`
-----------------

[](#the-magicobject)

The power of Monad comes from the `MagicObject` class, allowing you to create dynamic and expressive objects. Every framework service (App, Request, Response, DB) is a `MagicObject`.

`MagicObject`s allow you to define properties and closures that are resolved dynamically and "bound" to the instance.

```
$app = new App([
    // Closures are executed in the App context
    'greet' => function($app, $name) {
        return "Hello $name!";
    }
]);

echo $app->greet('World');
```

Services
--------

[](#services)

Monad acts as a giant Dependency Injection (DI) Container. You can register your own services using `$app->bind()` and access them using magic properties.

```
$app->bind('myService', function($app) {
    return new MyService();
});

$app->myService->sayHello();
```

This works, but you won't get any autocompletion for it. To fix that, just use the class/interface name as binding key and then retrieve the service using `$app->get()`:

```
$app->bind(MyService::class, function($app) {
    return new MyService();
});

$myService = $app->get(MyService::class);
$myService->sayHello(); // Autocomplete works fine :)
```

You can even override default services just by binding them again:

```
// Re-bind the internal db service to your custom implementation
$app->bind('db', function($app) {
    return new MyCustomDB(); // Must implement Monad\DB interface!
});

// Now you can use your custom DB implementation
$app->db->select('users', ['id' => 1]);
```

Just remember that when overriding internal services, custom services **must implement Monad interfaces** (i.e. `Monad\DB`) and you won't get any custom methods autocompletion for them.

---

Routing and Middleware
----------------------

[](#routing-and-middleware)

Registering routes is simple. Monad supports dynamic URL parameters and middleware.

```
// A global middleware
$app->use(function ($app, $next) {
    // Do something before...
    $response = $next($app);
    // Do something after...
    return $response;
});

// Route group protected by 'auth' middleware
$app->group('/admin', ['auth'], function($app) {

    $app->addRoute('GET', '/dashboard', function($app) {
        $app->response->render('admin.dashboard', ['title' => 'Admin Dashboard']);
    });

});
```

Full controllers are supported by passing an array `[Class::class, 'method']`.

---

Views and Templates
-------------------

[](#views-and-templates)

PHP is your templating engine, and Monad makes it safe and elegant. Data passed to the view is wrapped in a **recursive** context that provides automatic escaping and fluent helpers.

### Rendering

[](#rendering)

```
$app->response->layout = 'html.main_layout';
$app->response->render('html.pages.home', [
    'user' => ['name' => 'Sam', 'balance' => 1250.50],
    'items' => [['name' => 'Pizza', 'price' => 12], ['name' => 'Soda', 'price' => 2]]
]);
```

### Inside the Template (`html/pages/home.php`)

[](#inside-the-template-htmlpageshomephp)

```

Welcome,

Balance:  €

        :  €
