Step‑by‑Step Guide to Building a PHP MVC Framework from Scratch

This article provides a step‑by‑step guide to building a PHP MVC framework from scratch, covering MVC basics, directory structure, routing, controllers, models, views, core utilities, and includes sample code snippets throughout for developers.

php Courses
php Courses
php Courses
Step‑by‑Step Guide to Building a PHP MVC Framework from Scratch

MVC (Model‑View‑Controller) is a software architecture pattern that separates data, user interface, and control logic to improve maintainability and scalability of web applications.

1. Define core files and directories – create folders such as controllers/, models/, views/, and core/ to hold the main components of the framework.

- controllers/
- models/
- views/
- core/

2. Create routing – map URLs to controller actions. Example routes are defined in routes.php:

// routes.php
$routes = [
    '/' => 'HomeController@index',
    '/user' => 'UserController@index',
    '/user/create' => 'UserController@create',
    '/user/store' => 'UserController@store',
    '/user/edit/{id}' => 'UserController@edit',
    '/user/update/{id}' => 'UserController@update',
    '/user/delete/{id}' => 'UserController@delete',
];

3. Create controllers – handle requests and invoke models and views. Example UserController.php shows typical CRUD actions:

// controllers/UserController.php
class UserController {
    public function index() {
        $users = UserModel::all();
        View::render('users/index', $users);
    }

    public function create() {
        View::render('users/create');
    }

    public function store() {
        $user = new UserModel($_POST);
        $user->save();
        redirectTo('/user');
    }

    public function edit($id) {
        $user = UserModel::getById($id);
        View::render('users/edit', $user);
    }

    public function update($id) {
        $user = UserModel::getById($id);
        $user->fill($_POST);
        $user->save();
        redirectTo('/user');
    }

    public function delete($id) {
        $user = UserModel::getById($id);
        $user->delete();
        redirectTo('/user');
    }
}

4. Create models – interact with the database. Example UserModel.php provides static methods for fetching data and instance methods for persisting changes:

// models/UserModel.php
class UserModel {
    public static function all() {
        $result = DB::query('SELECT * FROM users');
        return $result;
    }

    public static function getById($id) {
        $result = DB::query('SELECT * FROM users WHERE id = ?', [$id]);
        return $result[0];
    }

    public function fill($data) {
        $this->name = $data['name'];
        $this->email = $data['email'];
        $this->password = $data['password'];
    }

    public function save() {
        if ($this->id) {
            DB::execute('UPDATE users SET name = ?, email = ?, password = ? WHERE id = ?', [$this->name, $this->email, $this->password, $this->id]);
        } else {
            DB::execute('INSERT INTO users (name, email, password) VALUES (?, ?, ?)', [$this->name, $this->email, $this->password]);
        }
    }

    public function delete() {
        DB::execute('DELETE FROM users WHERE id = ?', [$this->id]);
    }
}

5. Create views – render HTML for the user interface. Example views/users/index.php displays a table of users:

<!-- views/users/index.php -->
<h1>Users List</h1>
<table>
    <thead>
        <tr><th>Name</th><th>Email</th><th>Action</th></tr>
    </thead>
    <tbody>
        <?php foreach ($users as $user): ?>
            <tr>
                <td><?php echo $user['name']; ?></td>
                <td><?php echo $user['email']; ?></td>
                <td>
                    <a href="/user/edit/<?php echo $user['id']; ?>">Edit</a>
                    <a href="/user/delete/<?php echo $user['id']; ?>">Delete</a>
                </td>
            </tr>
        <?php endforeach; ?>
    </tbody>
</table>

6. Create core utilities – router, database wrapper, view renderer, and helper functions. Sample implementations are provided for Router.php, DB.php, View.php, and Helpers.php to handle request dispatching, PDO connections, template rendering, and redirects.

// core/Router.php
class Router {
    private static $routes = [];
    public static function addRoute($uri, $handler) { self::$routes[$uri] = $handler; }
    public static function dispatch($uri) {
        if (isset(self::$routes[$uri])) {
            $handler = self::$routes[$uri];
            list($controller, $action) = explode('@', $handler);
            $controller = 'controllers\' . $controller;
            $controller = new $controller;
            $controller->$action();
        } else {
            http_response_code(404);
            echo "404 Not Found";
        }
    }
}

// core/DB.php
class DB {
    private static $conn = null;
    public static function connect() {
        if (self::$conn === null) {
            self::$conn = new PDO('mysql:host=localhost;dbname=myapp', 'root', '');
        }
    }
    public static function query($sql, $params = []) {
        self::connect();
        $stmt = self::$conn->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    public static function execute($sql, $params = []) {
        self::connect();
        $stmt = self::$conn->prepare($sql);
        $stmt->execute($params);
    }
}

// core/View.php
class View {
    public static function render($view, $data = []) {
        extract($data);
        include "views/$view.php";
    }
}

// core/Helpers.php
function redirectTo($uri) { header("Location: $uri"); }

7. Deploy the application – upload all files to a server with PHP and MySQL, configure the web server (Apache or Nginx) to redirect all requests to index.php using an .htaccess file:

# .htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php [QSA,L]

After deployment, URLs are routed to index.php, which dispatches them to the appropriate controller actions, invoking models and views to generate responses.

The article concludes with a promotional note about a video course on the PHP Chinese website that teaches the complete framework implementation in 40 lessons for a limited price.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MVCroutingORMPHPFramework
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

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.