belinframework/framework

Lightweight PHP framework for building fast and scalable web applications.

Installs: 2

Dependents: 0

Suggesters: 0

Security: 0

Type:project

pkg:composer/belinframework/framework

dev-main 2026-01-07 19:17 UTC

This package is auto-updated.

Last update: 2026-01-07 19:17:36 UTC


README

A lightweight, modern PHP framework designed for building fast and scalable web applications.

Features

  • Fast: Minimal overhead with a lean core
  • 🎯 Productive: Craft CLI scaffolds controllers, services, routes, migrations, events, and tests
  • 🛣️ Routing: Router with grouping, middleware, and resource helpers
  • 📦 DI Container: Autowired services plus interface aliases
  • 🗄️ ORM & Migrations: Doctrine ORM/DBAL + migrations
  • 📬 Async & Queues: Sync/Redis queues with queue:work and event bus worker
  • 🛡️ Security & DX: CSRF, security headers, CORS, rate limiting, and env-specific config
  • 📨 Mail & Cache: Symfony Mailer and Symfony Cache integrations

Requirements

  • PHP 8.1 or higher
  • PDO and JSON extensions
  • Composer
  • Redis (optional, for Redis queue/event worker)

Installation

Method 1: Via Composer (recommended)

composer create-project belinframework/framework my-project
cd my-project

Method 2: Manual installation

git clone https://git.belin.uk/framework/belinframework.git my-project
cd my-project
composer install

Configure environment

php craft env:init        # Copies .env.example to .env (use --force to overwrite)
# or
cp .env.example .env

Key .env options (see .env.example for all):

  • App: APP_NAME, APP_ENV (development|production), APP_DEBUG, APP_TIMEZONE, ENABLE_MONITORING, APP_MAX_REQUEST_BODY
  • Database: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
  • Queue/Redis: QUEUE_DRIVER (sync|redis), REDIS_HOST, REDIS_PORT, REDIS_QUEUE
  • Rate limiting: RATE_LIMIT_POLICY, RATE_LIMIT_LIMIT, RATE_LIMIT_INTERVAL
  • Cache: CACHE_DRIVER, CACHE_PREFIX
  • Mail: SMTP_*, MAIL_FROM_ADDRESS, MAIL_FROM_NAME
  • CORS & Security: CORS_ALLOWED_ORIGINS, CORS_ALLOW_CREDENTIALS, CSRF_*, SECURITY_*, TRUSTED_PROXIES
  • Storage: STORAGE_ROOT

Start the development server:

php craft serve           # defaults to localhost:8000

Craft CLI

Preferred workflow: use php craft to scaffold controllers, entities, services, routes, migrations, events, and tests instead of creating files manually. Manual examples below are for reference only.

Make commands (what they generate)

  • make:crud <name>: Controller + service + entity/model + migration (full CRUD skeleton)
  • make:controller <name>: Controller in src/Controller
  • make:model <name> / make:entity <name>: Doctrine entity in src/Entity
  • make:service <name> [--no-interface]: Service class (and interface + DI wiring when interface is created)
  • make:middleware <name>: Middleware class
  • make:validation <name>: Validation class
  • make:error <name>: Custom exception
  • make:core <name>: Core utility
  • make:migration <name>: Doctrine migration file
  • make:event <name> / make:listener <name> [event]: Events and listeners
  • make:test <name> [--unit|--integration]: Test skeleton
  • make:route <path> <Controller@method> [--group name] [--prefix /api] [--middleware M1,M2] or --resource: Append router calls to config/routes.php (optionally inside a named group)

Utility & runtime

  • queue:work [--sleep ms]: Process jobs using the configured queue driver
  • queue:worker [--poll ms] [--batch size]: Event bus worker (Redis)
  • env:init [--force]: Create .env from the example file
  • delete <type> <name>: Remove generated files
  • serve [host:port]: Start the built-in PHP server
  • tinker: Interactive REPL
  • list: Show available commands

Routing

Routes live in config/routes.php. Prefer the Craft helper so routes are appended for you:

php craft make:route /api/users UserController@index GET
php craft make:route --resource posts PostController
# Add to a specific group (created automatically if missing)
php craft make:route /users UserController@index GET --group api --prefix /api --middleware AuthMiddleware
  • When using --group, pass paths without the group prefix (the group applies its own prefix).

Add the marker once inside config/routes.php so Craft knows where to append:

return function (Router $router): void {
    $router->get('/', [WelcomeController::class, 'index']);

    // Routes added by "php craft make:route" will appear below
};

Running the commands above will append something like:

    // Routes added by "php craft make:route" will appear below
    $router->get('/api/users', [\App\Controller\UserController::class, 'index']);

    // RESTful routes for posts
    $router->resource('/api/posts', \App\Controller\PostController::class);

    // api group
    $router->group([
        'prefix' => '/api',
        'middleware' => [
            \App\Middleware\AuthMiddleware::class,
        ],
    ], function (Router $router) {
        // Group "api" routes will appear below
        $router->get('/users', [\App\Controller\UserController::class, 'index']);
    });

Manual definition (if needed) still works:

use App\Core\Router;
use App\Controller\WelcomeController;
use App\Controller\UserController;

return function (Router $router): void {
    $router->get('/', [WelcomeController::class, 'index']);
    $router->get('/api/users', [UserController::class, 'index']);
};

Controllers

Generate controllers with php craft make:controller UserController (preferred). Manual example for reference:

namespace App\Controller;

use App\Core\BaseController;
use App\Core\Request;
use App\Core\Response;
use App\Service\UserService;

class UserController extends BaseController
{
    public function __construct(private UserService $users) {}

    public function index(Request $request): Response
    {
        return $this->success(['users' => $this->users->all()]);
    }
}

Services & DI

Use php craft make:service Payment to generate:

  • src/Service/PaymentService.php
  • src/Service/Interface/PaymentServiceInterface.php (unless --no-interface)
  • Auto-registration in config/services.php under concrete and aliases (Craft appends below its markers if present)

Manual registration example:

// config/services.php
return [
    'concrete' => [
        \App\Service\UserService::class,
        // Craft-generated services will be added below this line
    ],
    'aliases' => [
        \App\Service\Interface\UserServiceInterface::class => \App\Service\UserService::class,
        // Craft-generated aliases will be added below this line
    ],
];

Services are singletons and auto-wired by the container.

Queues & Events

  • Configure QUEUE_DRIVER=sync (default) or QUEUE_DRIVER=redis in .env
  • Push jobs via App\Queue\QueueManager; implement App\Queue\JobInterface
  • Run workers:
php craft queue:work --sleep 500        # job queue (sync/redis)
php craft queue:worker --poll 200 --batch 20  # event bus worker (Redis)

Project Structure

belinframework/
├── config/
│   ├── app.php
│   ├── cache.php
│   ├── cors.php
│   ├── database.php
│   ├── env/
│   ├── mail.php
│   ├── queue.php
│   ├── rate_limit.php
│   ├── routes.php
│   ├── security.php
│   ├── services.php
│   ├── storage.php
│   └── validation.php
├── public/           # Entry point (index.php)
├── resources/        # Views, fonts, assets
├── src/
│   ├── Console/
│   ├── Controller/
│   ├── Core/
│   ├── Data/
│   ├── Entity/
│   ├── Error/
│   ├── Event/
│   ├── Listener/
│   ├── Middleware/
│   ├── Model/
│   ├── Queue/
│   ├── Service/
│   ├── Validation/
│   ├── Config.php
│   └── helpers.php
├── tests/
├── craft             # Craft CLI entrypoint
├── composer.json
├── phpunit.xml
└── README.md

Testing

composer test

Code Style

composer phpcs   # check
composer phpcbf  # fix

License

MIT License

Author

Alberto Boschi - boschi.alberto1@gmail.com

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.