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 -> index.php /includes/ .htaccess In /includes/ -> /classes/ /controllers/ /routes/ /views/ In /classes/ -> _Globals.php How.php Route.php View.php In /controllers/ -> Controller.php Root.php In /Routes/ -> Route.php In /views/ -> root.php
index.php
<?php
include_once( 'includes/classes/How.php' );
$how = new How();
$how->run();
/includes/classes/How.php
<?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->getRoute();
} catch (Exception $e) {
die("Failed to get route.");
}
}
}
/includes/classes/Route.php
<?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->__invoke();
}
}
/includes/classes/View.php
<?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
<?php
$Routes = array();
define( 'BASEDIR', '/how/' );
/includes/controllers/Root.php (Controller.php is currently blank)
<?php
class RootController {
public static $username = "Francis";
}
/includes/Routes/Route.php
<?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
<h1>Welcome <?php echo RootController::$username; ?>!</h1>
.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->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 theRoute::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 theViewController
is loaded from /includes/controllers/.