Build a Simple MVC Framework in Pure PHP

Build a Simple MVC Framework in Pure PHP

Build a Simple MVC Framework in Pure PHP

Understanding how an MVC framework works makes you a better developer regardless of which framework you use. This project builds one from scratch in pure PHP.

Features

  • Front controller pattern with a single entry point
  • Regex-based router with named parameters
  • Controller dispatch and dependency injection
  • Simple template engine with layouts
  • PDO-based query builder

Step 1 — Entry Point & Directory Structure

project/
├── public/
│   └── index.php       # front controller
├── app/
│   ├── Controllers/
│   ├── Models/
│   └── Views/
├── core/
│   ├── Router.php
│   ├── Controller.php
│   ├── Model.php
│   └── View.php
└── routes.php

Step 2 — Router

class Router
{
    private array $routes = [];

    public function get(string $uri, array $action): void
    {
        $this->routes[] = ['method' => 'GET', 'uri' => $uri, 'action' => $action];
    }

    public function dispatch(string $method, string $uri): void
    {
        foreach ($this->routes as $route) {
            $pattern = preg_replace('/\{(\w+)\}/', '(?P<$1>[^/]+)', $route['uri']);
            if ($route['method'] === $method && preg_match("#^{$pattern}$#", $uri, $matches)) {
                [$controller, $action] = $route['action'];
                $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
                (new $controller)->{$action}(...$params);
                return;
            }
        }
        http_response_code(404);
        echo '404 Not Found';
    }
}

Step 3 — Base Model with PDO

class Model
{
    protected static string $table;
    protected static PDO $pdo;

    public static function all(): array
    {
        $stmt = static::$pdo->query("SELECT * FROM " . static::$table);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function find(int $id): ?array
    {
        $stmt = static::$pdo->prepare("SELECT * FROM " . static::$table . " WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
    }
}
All Comments