PHP code example of seba1rx / exhaust

1. Go to this page and download the library: Download seba1rx/exhaust library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

seba1rx / exhaust example snippets


use App\Controllers\Wellcome;
use App\Controllers\UserController;

$routes = new Route();

$routes->registerGetRoute('/', [Wellcome::class, 'showLandingPage'])->name('home');

$routes->registerPostRoute('/users', [UserController::class, 'store'])
       ->name('users.store')
       ->middlewares(['Authentication']);

$routes->registerGetRoute('/users/{id}', [UserController::class, 'show'])
       ->name('users.show');

$routes->registerPutRoute('/users/{id}', [UserController::class, 'update']);
$routes->registerDeleteRoute('/users/{id}', [UserController::class, 'destroy']);

// Single-action controller — no method, class must be invokable
$routes->registerDeleteRoute('/session', [\App\Controllers\Logout::class]);

namespace App\Controllers;

use App\Controllers\Controller;
use Exhaust\Response\Commands;

class UserController extends Controller
{
    public function edit(array $payload): array
    {
        $html = app()->render('user/edit.html.twig', ['id' => $payload['id']]);

        Commands::html('content-section', $html);

        return Commands::all();
    }

    public function destroy(array $payload): array
    {
        // … delete logic …

        Commands::dialog(type: 'success', options: Commands::dialogBuilder(
            icon: 'success',
            title: 'Deleted',
            btn_confirm: ['text' => 'Ok', 'callback' => "Engeen.route('/users')"],
        ));

        return Commands::all();
    }
}

namespace App\Controllers;

class Controller
{
    public function __construct(array $middlewares)
    {
        $this->invokeBeforeMiddlewares($middlewares, app()->request->payload);
    }
    // …
}

Commands::html('content-section', '<p>New content</p>');
Commands::html('sidebar', app()->render('partials/sidebar.twig', $data));

Commands::script("myApp.loadSection('profile'); myApp.highlightMenu('users');");

Commands::assignValue('currentUserId', 42);
Commands::assignValue('config', ['theme' => 'dark', 'lang' => 'es']);

// Recommended: use dialogBuilder for readable named parameters
Commands::dialog(type: 'success', options: Commands::dialogBuilder(
    icon: 'success',
    title: 'Saved',
    text: 'Your changes have been saved.',
    btn_confirm: ['text' => 'Ok', 'callback' => 'Engeen.route("/dashboard")'],
));

Commands::dialog(type: 'warning', options: Commands::dialogBuilder(
    icon: 'warning',
    title: 'Are you sure?',
    btn_confirm: ['text' => 'Yes, delete', 'class' => 'btn-danger', 'callback' => 'deleteItem()'],
    btn_cancel:  ['text' => 'Cancel'],
));

Commands::dialog(type: 'info', options: Commands::dialogBuilder(
    icon: 'info',
    title: 'Session expiring',
    timer: ['time' => 5000, 'callback' => 'logout()'],
    showLoading: true,
));

Commands::toast('success', [
    'title'    => 'Changes saved',
    'duration' => 3000,
    'position' => 'top-end',
]);

Commands::toast('error', ['title' => 'Something went wrong', 'duration' => 5000]);

Commands::log(type: 'info',    text: 'User created',   details: ['id' => 5]);
Commands::log(type: 'warning', text: 'Slow query',      details: ['ms' => 820]);
Commands::log(type: 'error',   text: 'Payment failed');
Commands::log(type: 'debug',   details: $payload);

Commands::console_log('checkpoint reached');
Commands::console_log(['key' => 'value', 'count' => 3]);

Commands::echo(html: app()->render('landing/landing.html.twig'));

Commands::apiResponse(['users' => $list, 'total' => count($list)]);

Commands:::script('renderChart(' . json_encode($data) . ')');

public function saveProfile(array $payload): array
{
    $bio = $payload['bio'] ?? '';

    if (empty($bio)) {
        Commands::dialog(type: 'warning', options: Commands::dialogBuilder(
            icon: 'warning',
            title: 'Validation error',
            text: 'Bio cannot be empty.',
        ));
        return Commands::all();
    }

    // persist …
    app()->dbLink->update(
        'UPDATE users SET bio = :bio WHERE id = :id',
        [':bio' => $bio, ':id' => $payload['userId']]
    );

    Commands::html('profile-bio', htmlspecialchars($bio));
    Commands::toast('success', ['title' => 'Profile updated', 'duration' => 3000, 'position' => 'top-end']);
    Commands::log(type: 'info', text: 'Profile saved', details: ['userId' => $payload['userId']]);

    return Commands::all();
}

app()->request->payload               // stdClass — all body params, type-cast automatically
app()->request->uri->path             // '/users/7'
app()->request->getRequestMethod()    // 'POST'
app()->request->isAsync()             // true for XHR and Fetch
app()->request->isNavigation()        // true for regular browser navigation
app()->request->getRemoteAddress()
app()->request->getUriParam('page')   // query string: ?page=2
app()->request->hasUpload()

use Exhaust\Contracts\RequestBlueprint;

// Type-hinting in a service or utility that receives the request
public function audit(RequestBlueprint $request): void
{
    $method  = $request->getRequestMethod(); // 'POST'
    $ip      = $request->getRemoteAddress(); // '192.168.1.10'
    $payload = $request->payloadAsArray();   // ['userId' => 7, 'action' => 'delete']
    $isXHR   = $request->isAsync();          // true
}

use Nyholm\Psr7\Factory\Psr17Factory;

$factory    = new Psr17Factory();
$psr7       = app()->request->toPsr7($factory);

// Pass to any PSR-15 middleware or PSR-7-aware library
$psr7       = $psr7->withAttribute('user', $currentUser);
$response   = $someExternalMiddleware->process($psr7, $handler);

namespace App\Middlewares;

use Exhaust\Contracts\MiddlewareBlueprint;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Nyholm\Psr7\Response;

final class AuthMiddleware implements MiddlewareBlueprint
{
    /**
     * Validates the session and either short-circuits with a redirect or
     * delegates to the next handler in the pipeline.
     *
     * @param ServerRequestInterface  $request
     * @param RequestHandlerInterface $handler
     * @return ResponseInterface
     */
    public function process(
        ServerRequestInterface  $request,
        RequestHandlerInterface $handler,
    ): ResponseInterface
    {
        if (!isset($_SESSION['user'])) {
            // Short-circuit: return a redirect without reaching the controller
            return (new Response(302))->withHeader('Location', '/login');
        }

        // Delegate to the next middleware or the controller
        return $handler->handle($request);
    }
}

namespace App\Middlewares;

final class AuthMiddleware
{
    /** Redirects to login if no active session exists. */
    public function __invoke(): void
    {
        if (!isset($_SESSION['user'])) {
            header('Location: /login');
            exit;
        }
    }
}

namespace App\Controllers;

use Exhaust\Contracts\MiddlewareBlueprint;
use Nyholm\Psr7\Factory\Psr17Factory;

class Controller
{
    public function __construct(array $middlewares)
    {
        $this->invokeBeforeMiddlewares($middlewares, app()->request->payload);
    }

    /**
     * Executes each middleware before the controller action.
     * Supports both PSR-15 (MiddlewareBlueprint) and legacy invokable middlewares.
     *
     * @param array     $middlewares List of middleware class names.
     * @param \stdClass $payload     Current request payload.
     * @return void
     */
    public function invokeBeforeMiddlewares(
        array $middlewares,
        \stdClass $payload = new \stdClass,
    ): void
    {
        $factory = new Psr17Factory();

        foreach ($middlewares as $className) {
            $middleware = new ("\\App\\Middlewares\\{$className}")();

            if ($middleware instanceof MiddlewareBlueprint) {
                // PSR-15 path
                $psr7    = app()->request->toPsr7($factory);
                $handler = new \App\Http\FinalHandler($factory);
                $middleware->process($psr7, $handler);
            } else {
                // Legacy invokable path
                $middleware($payload);
            }
        }

        if (app()->terminate_session) {
            app()->response = new \stdClass;
        }
    }
}

namespace App\Http;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

/**
 * Terminal handler for the PSR-15 middleware pipeline.
 *
 * Returns an empty 200 response — the actual response body is built by
 * Exhaust's Commands system and sent separately by app()->run().
 */
final class FinalHandler implements RequestHandlerInterface
{
    public function __construct(private readonly Psr17Factory $factory) {}

    /**
     * @param ServerRequestInterface $request
     * @return ResponseInterface
     */
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return $this->factory->createResponse(200);
    }
}

namespace App\Http;

use Exhaust\Contracts\ResponseBlueprint;
use Exhaust\Exceptions\LogicException;
use Exhaust\Request\RequestType;
use Exhaust\Tools\CastingTool;

/**
 * Wraps the validated Commands array and serialises it as HTML or JSON
 * depending on the originating request type.
 */
final class Response implements ResponseBlueprint
{
    /**
     * @param array       $commands    Validated command set from Commands::all().
     * @param RequestType $requestType Detected type of the originating request.
     */
    public function __construct(
        private readonly array       $commands,
        private readonly RequestType $requestType,
    ) {}

    /** {@inheritdoc} */
    public function getCommands(): array
    {
        return $this->commands;
    }

    /** {@inheritdoc} */
    public function toJson(): string
    {
        return json_encode(CastingTool::arrayToObject($this->commands));
    }

    /**
     * {@inheritdoc}
     * @throws LogicException When the Commands set has no 'echo' entry.
     */
    public function toHtml(): string
    {
        if (!isset($this->commands['echo'])) {
            throw new LogicException('Response has no echo command — cannot render HTML.');
        }
        return $this->commands['echo'];
    }

    /** {@inheritdoc} */
    public function send(): void
    {
        if ($this->requestType === RequestType::Navigation) {
            header('Content-Type: text/html; charset=UTF-8');
            echo $this->toHtml();
        } else {
            header('Content-Type: application/json; charset=utf-8');
            echo $this->toJson();
        }
    }
}

use Exhaust\Response\Commands;
use App\Http\Response;

// Build commands as usual …
Commands::html('content', $html);
Commands::toast('success', ['title' => 'Saved', 'duration' => 3000]);

// Wrap in the concrete Response and send
$response = new Response(
    commands:    Commands::all(),
    requestType: app()->request->requestType,
);
$response->send();

app()->render('folder/template.html.twig', ['user' => $user]);

Browser  ──XHR/Fetch──▶  PHP Controller  ──Commands JSON──▶  engeen.js

Client  ──HTTP──▶  PHP Controller  ──Plain JSON──▶  Client

your-app/
├── public/index.php            ← single entry point
├── public/assets/js/
│   ├── engeen.js               ← frontend engine
│   └── drivers/                ← dialog/toast drivers (SweetAlert2, Notiflix, …)
├── App/
│   ├── Controllers/
│   │   └── Controller.php      ← app-level base controller (handles middlewares)
│   ├── Middlewares/
│   └── Models/
├── config/
│   ├── config.php              ← global configuration
│   └── routes.php              ← route definitions
└── resources/templates/        ← views