PHP MVC implementation without a framework I've been using PHP for years and in every project I've ever done I've included the HTML, PHP, SQL etc ... in the same page. Upon looking through Github at large projects like WordPress and MediaWiki it appears there are much better ways to lay out your code. I want to use MVC for my next project because I plan on making the code open source. I don't want to use a framework because I don't want lots of overhead and I don't want to have to learn a new framework to be honest.

I've started implementing what I think is a very simple MVC framework for my project. Can anyone who has experience with MVC tell me if I'm doing this correctly?

My project is called How, hence the class names.

The file structure of my project looks like this:




Root directory   -&gt; index.php /includes/ .htaccess
In /includes/    -&gt; /classes/ /controllers/ /routes/ /views/
In /classes/     -&gt; _Globals.php How.php Route.php View.php
In /controllers/ -&gt; Controller.php Root.php
In /Routes/      -&gt; Route.php
In /views/       -&gt; root.php



index.php



&lt;?php
include_once( 'includes/classes/How.php' );

$how = new How();
$how-&gt;run();


/includes/classes/How.php

&lt;?php
include_once( './includes/routes/Routes.php' );

class How {
    public function getRoute() {
    global $Routes;
    $uri = $_SERVER['REQUEST_URI'];

    if (!in_array($uri, $Routes)) {
        die("Invalid route.");
    }
    return $uri;
    }

    public function run() {
        try {
            $this-&gt;getRoute();
        } catch (Exception $e) {
            die("Failed to get route.");
        }
    }
}


/includes/classes/Route.php

&lt;?php
include_once( '_Globals.php' );
class Route {

    private function registerRoute($route) {
        global $Routes;
        $Routes[] = BASEDIR.$route;
    }

    public static function set($route, $closure) {
        self::registerRoute($route);
        $closure-&gt;__invoke();
    }
}


/includes/classes/View.php

&lt;?php
    class View {
        public static function make($view) {
            try {
                include( './includes/controllers/'.$view.'.php' );
                include('./includes/views/'.$view.'.php');
                return 1;
            } catch ( Exception $e ) {
                return 0;
            }
        }
    }


/includes/classes/_Globals.php

&lt;?php
$Routes = array();
define( 'BASEDIR', '/how/' );


/includes/controllers/Root.php (Controller.php is currently blank)

&lt;?php
class RootController {
    public static $username = "Francis";
}


/includes/Routes/Route.php

&lt;?php
include_once( './includes/classes/Route.php' );
include_once( './includes/classes/View.php' );

Route::set('', function() {
    View::make('root');
});

Route::set("about-us", function() {
});


/includes/views/root.php

&lt;h1&gt;Welcome &lt;?php echo RootController::$username; ?&gt;!&lt;/h1&gt;


.htaccess

RewriteEngine On
RewriteRule ^([^/]+)/? index.php?url=$1 [L,QSA]


It works like this:


The .htaccess redirects all requests to index.php.
Index.php calls how-&gt;run() which checks if the current route is valid.
Valid routes are stored in the global $Routes array, they are added to the $Routes array by the Route::set() method in the Routes/Route.php.
If the route is valid the View::make() method is called which loads the view from /includes/views/ and the ViewController is loaded from /includes/controllers/.
Before you consider any answer, always consider the rule that you should not write code which is not helpful and avoid code which is unused. When you are using an external framework there is a community which maintains it for you. Here its only you who is the expert. 


Less code you write, less maintenance &amp; faster development time.
More readable and maintainable code, easier it is.


Feedback on your code. 


Routes.php is quite simplistic. It is not necessarily bad but you havent considered how you would pass on different types of values.
The framework considers only routing as the primary goal of the framework. But you havent considered other things like DB query, Caching, Templating, Security. etc
You are loosing a lot of flexibility in file management when with the current routes framework.


In addition to the above I suggest including two more pieces of code.


A general file (include_top.php) which gets included in top of all files. It might look something like the following

&lt;?
session_start();
//do some global configurations
function __autoload($className) {
    // Put your own directory structure here //
    if(file_exists("../classes/$className.php"))
    include_once "../classes/$className.php";
}
?&gt;


This helps you to easily structure your code into different folders without worry about certain import statements having right path and doing additional global configurations.
An ORM (Object-relational mapping) is a must for any scalable
framework. You can checkout existing frameworks already. I will put a plug for my own light weight ORM.