biurad/flange

A fast micro, compilable, and scalable PHP framework

v1.1.3 2019-03-30 05:54 UTC

This package is auto-updated.

Last update: 2024-02-22 09:32:24 UTC


README

PHP Version Latest Version Workflow Status Code Maintainability Coverage Status Quality Score

Flange is an incredibly fast, compilable and scalable framework for PHP 8.0+ based on PSR-7, PSR-11, PSR-14 and PSR-15 with support for annotations/attributes, created by Divine Niiquaye.

This library is shipped with lots of features that suites developers needs in developing web applications. Flange is truly scalable, has less dependencies and has high performance.

Flange v2.0 is in early stage development and is not recommended for production use.

📦 Installation & Basic Usage

This project requires PHP 8.0 or higher. The recommended way to install, is via Composer. Simply run:

$ composer require biurad/flange 2.0.*

Flange is built based on Flight Routing, Biurad DI, Symfony components and Biurad libraries. Flange is a fully PSR complaint PHP framework, fully customizable and can even be used to develop from small to large projects:

require_once __DIR__ . '/vendor/autoload.php';

// Boot the application.
$app = new Flange\Application();

// Add a route to application
$app->match('/hello/{name:\w+}', to: fn (string $name): string => 'Hello ' . $app->escape()->escapeHtml($name));

$extensions = [
    [Flange\Extensions\CoreExtension::class, [__DIR__]],
    // You can add more extensions here ...
];

//If you want to use extensions, here is an example:
$app->loadExtensions($extensions, ['config' => '%project_dir%/config']);

// You can set custom pages for caught exceptions, using default event dispatcher, or your custom event dispatcher.
$app->getDispatcher()?->addListener(Flange\Events::EXCEPTION, new ErrorListener(), -8);

$app->run();

Working on a big project!, it is advisable to use the application's cacheable version. This gives you over 60% - 100% more performance than using the un-cacheable Application class with extensions.

use function Rade\DI\Loader\{param, phpCode, wrap};

$config = [
    'cacheDir' => __DIR__ . '/caches',
    'debug' => $_ENV['APP_DEBUG'] ?? false, // Set the debug mode environment
];

// Setup cache for application.
$app = Flange\AppBuilder::build(static function (Flange\AppBuilder $creator): void {
    // Add resource to re-compile if changes are made to this file.
    $creator->addResource(new FileResource(__FILE__));

    // Adding routes requires the Rade\DI\Extensions\RoutingExtension to be loaded.
    // Routes should always be added before Rade\DI\Extensions\RoutingExtension is booted, else it will not be compiled.
    $creator->match('/hello/{name:\w+}', to: phpCode('fn (string $name): string => \'Hello \' . $this->escape()->escapeHtml($name);'));

    $extensions = [
        [Flange\Extensions\CoreExtension::class, [__DIR__]],
        // You can add more extensions here ...
    ];

    //If you want to use extensions, here is an example as its recommended to use extensions to build your application.
    $creator->loadExtensions($extensions, ['config' => '%project_dir%/config']);

    // You can set custom pages for caught exceptions, using default event dispatcher, or your custom event dispatcher.
    $creator->definition('events.dispatcher')->bind('addListener', [Flange\Events::EXCEPTION, wrap(ErrorListener::class), -8]);
}, $config);

$app->run(); // Boot the application.

Here's an example of a custom error you can use for your application.

use Biurad\Http\Response\HtmlResponse;
use Flange\Event\ExceptionEvent;

class ErrorListener
{
    public function __invoke(ExceptionEvent $event): void
    {
        // If extensions were loaded, the %project_dir% will exist, else replace will absolute path
        $errorsPath = $event->getApplication()->parameter('%project_dir%/errors/');

        $code = $event->getThrowable()->getCode();
        $templates = [
            $errorsPath . \substr($code, 0, 2) . 'x.html.php', // 40x.html.php format ...
            $errorsPath . \substr($code, 0, 1) . 'xx.html.php', // 4xx.html.php format ...
            $errorsPath . $code . '.html.php', // 404.html.php format ...
            $errorsPath . 'default.html.php',
        ];

        // Tries to load a template file from a list of error templates.
        foreach ($template as $template) {
            if (\file_exists($template)) {
                $event->setResponse(
                    (static function () use ($template, $code) {
                        \ob_start();
                        include __DIR__ . $template;

                        return new HtmlResponse(\ob_get_clean(), (int) $code);
                    })()
                );
            }
        }
    }
}

Important to note that, using PSR-15 middlewares stack uses the PHP SPL Queue class with the following algorithm, LAST <- FIRST : FIRST -> LAST. Loading extensions and events listeners by default uses the priority stacking algorithm (which means the higher the priority, the earlier an extension or event listener will be triggered in the chain) which defaults to 0.

📓 Documentation

In-depth documentation on how to use this library, kindly check out the documentation for this library. It is also recommended to browse through unit tests in the tests directory.

🙌 Sponsors

If this library made it into your project, or you interested in supporting us, please consider donating to support future development.

👥 Credits & Acknowledgements

📄 License

Flange is completely free and released under the BSD 3 License.