I have a problem building a front controller for a project I have at school. Here is the thing, i created several controllers per entities i.e. One to select, another one to del
You will want to build a basic router, what it does.
A router will parse the path and take parts of it and locate a controller file. And then run a method in that file with arguments. We will use this format for urls
www.yoursite.com/index.php/{controller}/{method}/{args}
So for this example our url will be
www.yoursite.com/index.php/home/index/hello/world
the index.php
can be hidden using some basic .htaccess ( Mod Rewrite )
So lets define some things, first we will have folders
-public_html
index.php
--app
---controller
home.php
So the main folder is public_html
with the index.php
and a folder named app
. Inside app
is a folder named controller
and inside that is our home.php
contoller
Now for the Code ( yea )
index.php (basic router )
0 ? array_shift($args) : 'index'; //remove second item or default to index ( method )
$basepath = __DIR__.'/app/controller/'; //base path to controllers
if(!file_exists($basepath.$controller_class.".php") ){
echo "SHOW 404";
exit();
}
//instantiate controller class
require_once $basepath.$controller_class.".php";
$Controller = new $controller_class;
//check if method exists in controller
if(!method_exists( $Controller, $method ) ){
echo "Method not found in controller / or 404";
exit();
}
//call methods with any remaining args
call_user_func_array( [$Controller, $method], $args);
home.php ( controller )
Now if you put in any of these urls
www.yoursite.com/index.php
www.yoursite.com/index.php/home
www.yoursite.com/index.php/home/index
It should print ( defaults )
Arg1:
Arg2:
If you do this url
www.yoursite.com/index.php/home/index/hello/world
It should print
Arg1: hello
Arg2: world
And if you do this one
www.yoursite.com/index.php/home/test/hello_world
it would print
Arg1: hello_world
The last one, running in the second method test
( no echo arg2 ), this way you can see how we can add more controllers and methods with only having to code them into a controller.
This method still allows you to use the $_GET
part of the url, as well as the URI part to pass info into the controller. So this is still valid
www.yoursite.com/index.php/home/test/hello_world?a=1
and you could ( in home::test() ) output the contents of $_GET
with no issues, this is useful for search forms etc. Some pretty url methods prevent this which is just ... well ... crap.
In .htaccess
with mod rewrite you would do this to remove index.php from the urls
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
Then you can use urls without the index.php such as this
www.yoursite.com/home/index/hello/world
This is the simplest Router I could come up with on such short notice, yes I just created it. But this is a very similar ( although simplified ) implementation used in many MVC frameworks
PS. please understand how this is all done, so you actually learn something...
Many improvements could be made, such as allowing these urls
www.yoursite.com/hello/world
www.yoursite.com/home/hello/world
www.yoursite.com/index/hello/world
Which would all fall back to the a default of home controller and index method, but that would take some additional checks (for not found files and methods ) I cant be bothered with right now...