Developer documentation for the lightweight, PHP-FPM-oriented Bhitti framework.
Controllers normally live in app/Controllers/ and are resolved through Bhitti’s service container only after route middleware succeeds.
<?php
declare(strict_types=1);
namespace App\Controllers;
use Bhitti\Http\Response;
final class UserController extends Controller
{
public function index(): Response
{
$users = db()
->table('users')
->select('id', 'name', 'email')
->get();
return response()->json(['users' => $users]);
}
}
Concrete constructor dependencies are autowired:
final class ReportController extends Controller
{
public function __construct(private ReportService $reports)
{
}
}
Bind interfaces or custom implementations in container configuration when automatic construction is not enough.
Bhitti supports middleware directly on controller classes and methods through the repeatable #[Middleware] PHP attribute.
Import the attribute and middleware class:
use App\Middlewares\Guest;
use App\Middlewares\RoleMiddleware;
use Bhitti\Http\Middleware\Attributes\Middleware;
A class-level attribute applies to every routed method on that controller:
#[Middleware(RoleMiddleware::class, ['user'])]
final class ProfileController extends Controller
{
public function index(): string
{
return response()->view('profile.index');
}
}
A method-level attribute applies only to that action:
final class AuthController extends Controller
{
#[Middleware(Guest::class)]
public function registrationProcess(): Response
{
// ...
}
}
The attribute is repeatable, so multiple middleware may be declared:
#[Middleware(Authenticated::class)]
#[Middleware(RoleMiddleware::class, ['admin'])]
public function dashboard(): string
{
return response()->view('admin.dashboard');
}
Controller attributes are collected when routes are registered. They are stored in the prepared route handler and therefore included in the route cache. Rebuild the route cache after changing controller middleware attributes:
php run route:cache
For a matched route, middleware executes in this order:
config/routes.php,Route parameters are passed to the controller method:
public function show(int $id): Response
{
$user = db()->table('users')->find($id);
return response()->json(['user' => $user]);
}
Bhitti does not inject the Request object into controller methods. Use request() when needed.
view() returns the rendered string:
public function index(): string
{
return response()->view('welcome', ['title' => 'Bhitti']);
}