Backend Development 8 min read

Building a Simple PHP MVC Framework from Scratch

This tutorial guides you step‑by‑step through creating a basic PHP MVC framework, covering MVC concepts, Composer setup, project structure, core components like routing and controllers, view rendering, model creation, and testing the application with the built‑in PHP server.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Building a Simple PHP MVC Framework from Scratch

MVC is a widely used design pattern in software development, especially for web applications, that separates an application into three interconnected components: Model, View, and Controller. This layered structure improves modularity, maintainability, and development ease.

The Model (M) represents the application's data and business logic, handling data retrieval, manipulation, and storage.

The View (V) serves as the presentation layer, displaying data to the end user.

The Controller (C) acts as a mediator between Model and View, receiving user input, determining which models to invoke, and which view to render.

The MVC pattern enforces separation of concerns, making applications easier to understand, maintain, and extend.

Prerequisites

In this tutorial you will learn how to build a simple PHP MVC framework from scratch. You should have a basic understanding of the following:

PHP OOP concepts

Composer – the PHP package manager

HTML/CSS – not required for the framework itself but needed for the rendered pages

Setting Up the Project

To create a new Composer project, follow these steps:

Create a new directory and name it after your project.

Open the directory in your editor.

Run composer init in the terminal.

<code>composer init</code>

During composer init you can press Enter to skip all questions except development dependencies. When prompted to add dependencies, type no .

For simplicity, rename the namespace to a short name such as App by editing the composer.json file’s psr-4 entry:

<code>"Maheshsamudra\SimplePhpMvcStarter\" => "App\"</code>

Then run composer dump-autoload to update the autoloader.

Directory Structure

<code>public/   # web‑root
src/
  Controllers/
  Models/
  Routes/
  Views/
vendor/   # created automatically by Composer</code>

Building Core Components

Public Folder

Create public/index.php as the application entry point:

<code>&lt;?php

require '../vendor/autoload.php';

$router = require '../src/Routes/index.php';
</code>

Routing

Create src/Router.php to map routes to controllers:

<code>&lt;?php

namespace App;

class Router
{
    protected $routes = [];

    private function addRoute($route, $controller, $action, $method)
    {
        $this->routes[$method][$route] = ['controller' => $controller, 'action' => $action];
    }

    public function get($route, $controller, $action)
    {
        $this->addRoute($route, $controller, $action, "GET");
    }

    public function post($route, $controller, $action)
    {
        $this->addRoute($route, $controller, $action, "POST");
    }

    public function dispatch()
    {
        $uri = strtok($_SERVER['REQUEST_URI'], '?');
        $method = $_SERVER['REQUEST_METHOD'];

        if (array_key_exists($uri, $this->routes[$method])) {
            $controller = $this->routes[$method][$uri]['controller'];
            $action = $this->routes[$method][$uri]['action'];

            $controller = new $controller();
            $controller->$action();
        } else {
            throw new \Exception("No route found for URI: $uri");
        }
    }
}
</code>

Set the initial route in src/Routes.php :

<code>&lt;?php

use App\Controllers\HomeController;
use App\Router;

$router = new Router();

$router->get('/', HomeController::class, 'index');

$router->dispatch();
</code>

Controller – Handling the Home Page

Create a base controller in src/Controller.php :

<code>&lt;?php

namespace App;

class Controller
{
    protected function render($view, $data = [])
    {
        extract($data);
        include "Views/{$view}.php";
    }
}
</code>

Then create src/Controllers/HomeController.php extending the base controller:

<code>&lt;?php

namespace App\Controllers;

use App\Controller;

class HomeController extends Controller
{
    public function index()
    {
        $this->render('index');
    }
}
</code>

Adding the View

Create src/Views/index.php with a welcome message:

<code>&lt;h1&gt;Welcome to Simple PHP MVC Starter!&lt;/h1&gt;
</code>

Test the application by running the built‑in PHP server:

<code>cd simple-php-mvc-starter
php -S localhost:9999
</code>

Visiting http://localhost:9999 should display the welcome heading.

Creating a Model

Add src/Models/Journal.php to represent a journal entity:

<code>&lt;?php

namespace App\Models;

class Journal
{
    public $name;
    public $publishedYear;

    public function __construct($name, $publishedYear)
    {
        $this->name = $name;
        $this->publishedYear = $publishedYear;
    }
}
</code>

Update HomeController to load a list of journals and pass them to the view, then modify src/Views/index.php to display the list:

<code>&lt;h1&gt;Welcome to Simple PHP MVC Starter!&lt;/h1&gt;

&lt;ul&gt;
    &lt;?php foreach ($journals as $journal) : ?&gt;
        &lt;li&gt;&lt;?= $journal->name ?&gt; (&lt;?= $journal->publishedYear ?&gt;)&lt;/li&gt;
    &lt;?php endforeach; ?&gt;
&lt;/ul&gt;
</code>

With these steps you have built a functional PHP MVC framework from the ground up, gaining valuable experience for your résumé.

MVCframeworkComposer
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.