Middleware provides a convenient mechanism for filtering HTTP requests entering your application. Use middleware for authentication, logging, CORS, and more.
php mini make:middleware AuthMiddleware
This creates a middleware file at:
app/Middleware/AuthMiddleware.php
<?php
namespace App\Middleware;
use Core\Middleware;
use Core\Request;
use Core\Response;
class AuthMiddleware extends Middleware
{
/**
* Handle the incoming request
*/
public function handle(Request $request, \Closure $next)
{
// Your middleware logic here
// Continue to next middleware or route handler
return $next($request);
}
}
All middleware must:
Core\Middleware classApp\Middleware namespacehandle() method$next($request) to continue the requestpublic function handle(Request $request, \Closure $next)
{
// Execute code BEFORE the route handler
// Check conditions, modify request, etc.
if (/* some condition */) {
// Stop execution and return response
return Response::text('Unauthorized', 401);
}
// Continue to next middleware or route handler
$response = $next($request);
// Execute code AFTER the route handler (optional)
return $response;
}
<?php
namespace App\Middleware;
use Core\Middleware;
use Core\Request;
use Core\Response;
class AuthMiddleware extends Middleware
{
/**
* Handle the incoming request
* Check if user is authenticated
*/
public function handle(Request $request, \Closure $next)
{
// Check if user is logged in (example using session)
session_start();
if (!isset($_SESSION['user_id'])) {
// Redirect to login page
return Response::redirect('/login');
}
// User is authenticated, continue
return $next($request);
}
}
To use middleware with short names (like 'auth' instead of 'AuthMiddleware'), register aliases in your bootstrap file:
<?php
// public/index.php
require __DIR__ . '/../core/App.php';
$app = new \Core\App();
// Register middleware aliases
$app->middlewareAlias('auth', 'AuthMiddleware');
$app->middlewareAlias('admin', 'AdminMiddleware');
$app->middlewareAlias('guest', 'GuestMiddleware');
// Or register multiple at once
$app->middlewareAliases([
'auth' => 'AuthMiddleware',
'admin' => 'AdminMiddleware',
'guest' => 'GuestMiddleware'
]);
$app->run();
// Apply middleware to a single route
Route::middleware('auth')
->get('/dashboard', 'DashboardController@index');
// Multiple middleware
Route::middleware(['auth', 'admin'])
->get('/admin', 'AdminController@index');
// Apply middleware to multiple routes
Route::group(['middleware' => 'auth'], function () {
Route::get('/profile', 'UserController@profile');
Route::get('/settings', 'UserController@settings');
Route::get('/dashboard', 'DashboardController@index');
});
// Multiple middleware in group
Route::group(['middleware' => ['auth', 'verified']], function () {
Route::get('/email/verify', 'VerificationController@show');
});
Middleware executes in the following order:
Request → Global Middleware → Group Middleware → Route Middleware → Controller → Response
// Global middleware (in App)
$app->middleware('LoggingMiddleware');
// Route group
Route::group(['middleware' => 'auth'], function () {
// Route with additional middleware
Route::middleware('admin')
->get('/admin', 'AdminController@index');
});
// Execution order:
// 1. LoggingMiddleware
// 2. AuthMiddleware (from group)
// 3. AdminMiddleware (from route)
// 4. AdminController@index
<?php
namespace App\Middleware;
use Core\Middleware;
use Core\Request;
use Core\Response;
class AdminMiddleware extends Middleware
{
public function handle(Request $request, \Closure $next)
{
session_start();
// Check if user is admin
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
return Response::text('Forbidden', 403);
}
return $next($request);
}
}
<?php
namespace App\Middleware;
use Core\Middleware;
use Core\Request;
use Core\Response;
class CorsMiddleware extends Middleware
{
public function handle(Request $request, \Closure $next)
{
// Set CORS headers
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
// Handle preflight requests
if ($request->method() === 'OPTIONS') {
return Response::text('', 200);
}
return $next($request);
}
}
<?php
namespace App\Middleware;
use Core\Middleware;
use Core\Request;
use Core\Response;
class RateLimitMiddleware extends Middleware
{
public function handle(Request $request, \Closure $next)
{
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$key = "rate_limit_{$ip}";
// Simple rate limiting (use Redis or database in production)
$file = sys_get_temp_dir() . '/' . md5($key) . '.txt';
if (file_exists($file)) {
$data = json_decode(file_get_contents($file), true);
$count = $data['count'] ?? 0;
$time = $data['time'] ?? time();
// Reset if more than 1 minute passed
if (time() - $time > 60) {
$count = 0;
$time = time();
}
// Check limit (100 requests per minute)
if ($count >= 100) {
return Response::text('Too Many Requests', 429);
}
$count++;
} else {
$count = 1;
$time = time();
}
file_put_contents($file, json_encode(['count' => $count, 'time' => $time]));
return $next($request);
}
}
$next($request).
Now that you understand middleware, learn about: