Controllers
Controllers allow you to organize your route logic into classes instead of using closures. Sroute supports both controller classes and anonymous functions.
Using Anonymous Functions
Section titled “Using Anonymous Functions”For simple routes, you can use closures directly:
<?php
use Krag\Sroute\Router;
$router = new Router();
$router->get('/', function() { echo 'Welcome to the homepage!';});
$router->get('/about', function() { require __DIR__ . '/views/about.php';});With Route Parameters
Section titled “With Route Parameters”$router->get('/user/{id}', function(string $id) { echo "User ID: " . htmlspecialchars($id);});
$router->get('/post/{slug}/comment/{commentId}', function(string $slug, string $commentId) { echo "Post: {$slug}, Comment: {$commentId}";});Using Controller Classes
Section titled “Using Controller Classes”For complex applications, organize your logic into controller classes:
Creating a Controller
Section titled “Creating a Controller”<?php
namespace Controllers;
class HomeController{ public function index() { require __DIR__ . '/../views/home.php'; }
public function about() { require __DIR__ . '/../views/about.php'; }}Registering Controller Routes
Section titled “Registering Controller Routes”use Krag\Sroute\Router;use Controllers\HomeController;
$router = new Router();
$router->get('/', HomeController::class, 'index');$router->get('/about', HomeController::class, 'about');Controller with Parameters
Section titled “Controller with Parameters”Controllers automatically receive route parameters:
<?php
namespace Controllers;
class UserController{ public function show(string $id) { // Fetch user from database $user = $this->findUser($id);
require __DIR__ . '/../views/user/profile.php'; }
public function edit(string $id) { $user = $this->findUser($id);
require __DIR__ . '/../views/user/edit.php'; }
private function findUser(string $id) { // Database logic here return ['id' => $id, 'name' => 'John Doe']; }}$router->get('/user/{id}', UserController::class, 'show');$router->get('/user/{id}/edit', UserController::class, 'edit');Real-World Example
Section titled “Real-World Example”Here’s a complete controller handling a resource:
<?php
namespace Controllers;
class ProductController{ public function index() { // List all products $products = $this->getAllProducts(); require __DIR__ . '/../views/products/index.php'; }
public function show(string $id) { // Show single product $product = $this->findProduct($id);
if (!$product) { http_response_code(404); echo 'Product not found'; return; }
require __DIR__ . '/../views/products/show.php'; }
public function create() { // Show create form require __DIR__ . '/../views/products/create.php'; }
public function store() { // Validate and save new product $name = $_POST['name'] ?? ''; $price = $_POST['price'] ?? 0;
if (empty($name)) { $_SESSION['errors'] = ['name' => 'Name is required']; header('Location: /products/create'); exit; }
$this->saveProduct(['name' => $name, 'price' => $price]);
header('Location: /products'); exit; }
private function getAllProducts() { // Database query return []; }
private function findProduct(string $id) { // Database query return null; }
private function saveProduct(array $data) { // Database insert }}Routes for the Controller
Section titled “Routes for the Controller”use Controllers\ProductController;
// List products$router->get('/products', ProductController::class, 'index') ->name('products.index');
// Show create form$router->get('/products/create', ProductController::class, 'create') ->middleware(['auth']) ->name('products.create');
// Store new product$router->post('/products', ProductController::class, 'store') ->middleware(['auth', 'csrf']) ->name('products.store');
// Show single product$router->get('/products/{id}', ProductController::class, 'show') ->name('products.show');Controller Organization
Section titled “Controller Organization”Organize controllers by feature or resource:
Controllers/├── Auth/│ ├── LoginController.php│ └── RegisterController.php├── Admin/│ ├── DashboardController.php│ └── UserController.php├── HomeController.php└── ProductController.phpBest Practices
Section titled “Best Practices”- Single Responsibility: Each controller should handle one resource or feature
- Keep methods focused: Controller methods should be concise and delegate to services/repositories
- Use dependency injection: Pass dependencies through the constructor when needed
- Return early: Use early returns for validation failures
- Separate concerns: Move business logic to service classes, keep controllers thin