I’ve created a complete working MVC project with routing for you in the canvas.
This is not just theory — you can copy this and run it directly.
🚀 How to run it
- Create the folder structure exactly as shown
- Put files in correct folders
- Enable Apache
mod_rewrite - Open in browser:
http://localhost/→ Home pagehttp://localhost/Home/users→ Users page
🔥 What this project includes
- Clean MVC structure
- Custom Router (no framework)
- Dynamic URL handling
- Controller → Model → View flow
- Reusable base controller
<?php
// ===============================
// PROJECT STRUCTURE
// ===============================
/*
/project
│
├── /app
│ ├── /controllers
│ │ └── HomeController.php
│ │
│ ├── /models
│ │ └── UserModel.php
│ │
│ └── /views
│ ├── home.php
│ └── users.php
│
├── /core
│ ├── Router.php
│ └── Controller.php
│
├── /public
│ └── index.php
│
└── .htaccess
*/
// ===============================
// .htaccess (URL Routing)
// ===============================
/*
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ public/index.php?url=$1 [QSA,L]
*/
// ===============================
// public/index.php (Entry Point)
// ===============================
require_once '../core/Router.php';
$url = $_GET['url'] ?? '';
$router = new Router();
$router->dispatch($url);
// ===============================
// core/Router.php
// ===============================
class Router {
public function dispatch($url) {
$url = trim($url, '/');
$parts = explode('/', $url);
$controllerName = !empty($parts[0]) ? ucfirst($parts[0]) . 'Controller' : 'HomeController';
$method = $parts[1] ?? 'index';
$controllerFile = "../app/controllers/$controllerName.php";
if (!file_exists($controllerFile)) {
die('Controller not found');
}
require_once $controllerFile;
$controller = new $controllerName();
if (!method_exists($controller, $method)) {
die('Method not found');
}
$controller->$method();
}
}
// ===============================
// core/Controller.php (Base Controller)
// ===============================
class Controller {
public function view($view, $data = []) {
extract($data);
require "../app/views/$view.php";
}
}
// ===============================
// app/controllers/HomeController.php
// ===============================
require_once '../core/Controller.php';
require_once '../app/models/UserModel.php';
class HomeController extends Controller {
public function index() {
$this->view('home', ['title' => 'Welcome MVC']);
}
public function users() {
$model = new UserModel();
$users = $model->getUsers();
$this->view('users', ['users' => $users]);
}
}
// ===============================
// app/models/UserModel.php
// ===============================
class UserModel {
public function getUsers() {
return [
['name' => 'Aditya'],
['name' => 'Rahul'],
['name' => 'Priya']
];
}
}
// ===============================
// app/views/home.php
// ===============================
?>
<!DOCTYPE html>
<html>
<head>
<title><?= $title ?></title>
</head>
<body>
<h1><?= $title ?></h1>
<a href="/Home/users">View Users</a>
</body>
</html>
<?php
// ===============================
// app/views/users.php
// ===============================
?>
<!DOCTYPE html>
<html>
<head>
<title>Users</title>
</head>
<body>
<h2>User List</h2>
<ul>
<?php foreach($users as $user): ?>
<li><?= $user['name'] ?></li>
<?php endforeach; ?>
</ul>
<a href="/">Back Home</a>
</body>
</html>






