Jump to content

Front controller for the entire site, or more smaller ones?


Matic

Recommended Posts

Hey, I was asking a lot of questions lately on this forum and it all boiled down to this one. We all know it is hype to implement front controller or master page index.php that handles all the requests to all the pages and reroutes you etc... All this for cleaner urls, easier code handling...

 

But what if you have a browser game with a lot of locations and variables, states, conditions etc.. I can't write a million if statements or switch statements on my index page. What if I implement such page structure as described below? Basicly you don't have single point of entry or one front controller but more main controllers that connect to subcontrollers:


                                                                  if location forest
                     if loged in                             |---------------------------- forest.php
                  |------------------ start.php -------------|
                  |                                          |    if location home
                  |                                          |-------------------------- homebase.php
                  |                                          |   
                  |                                          |    if location else
index.php---------|                                          |------------------------- anywhere.php
                  |
                  |  if in fight
                  |------------------- combat.php
                  |
                  |  if not loged in
                  |------------------- homepage.php

Why would all pages have to go through index.php? This would be a big mess! Divide pages based on location, for example my start.php page will decide where to redirect further. So in this case I have two bigger controllers not just one front one. Is this still a good convention? I mean is this still a good front controll design or is it better to leave all the redirects to index.php?

Edited by Matic
Link to comment
Share on other sites

But what if you have a browser game with a lot of locations and variables, states, conditions etc.. I can't write a million if statements or switch statements on my index page.

You wouldn't write a million if or switch statements, you'd consolidate all your possible paths into some kind of array (or database) and then loop through them to determine where to go. For example:

$routes = array(
   array(
     'matches' => '^/fight/(\d+)$'
     , 'controller' => 'combat.php'
   )
   , array(
     'matches' => '^/village/(\d+)$'
     , 'controller' => 'village.php'
   )
   , array(
     'matches' => '^/shop/(\d+)$'
     , 'controller' => 'shop.php'
   )
   , array(
     'matches' => '^/shop/(\d+)/buy/(\d+)$'
     , 'controller' => 'shop.php'
   )
);
foreach ($routes as $rt){
   if (preg_match($rt['matches'], $_SERVER['REQUEST_URI'], $urlparams)){
      include $rt['controller'];
   }
}
That is just a simplistic idea, you could expand on it greatly. Edited by kicken
Link to comment
Share on other sites

Here is an idea, if you use includes to show pages on index.php right? Those included pages can also have includes of other pages! So in reality you get a tree like hierchy, pages you included under certain circumstances, include other pages in certain circumstances, etc...

 

Am I right here, or this is nothing like that?

Edited by Matic
Link to comment
Share on other sites

You could defer more specific processing to the child controller if you wanted. In my example above, I have two entries for shop.php, both begin '/shop/(\d+)' with the URL match. If you wanted, you could have just a single entry in your main control matching that prefix, then inside shop.php test more specific conditions such as '/shop/(\d+)/buy/(\d+)' or '/shop/(\d+)/sell/(\d+)'

Link to comment
Share on other sites

You could defer more specific processing to the child controller if you wanted. In my example above, I have two entries for shop.php, both begin '/shop/(\d+)' with the URL match. If you wanted, you could have just a single entry in your main control matching that prefix, then inside shop.php test more specific conditions such as '/shop/(\d+)/buy/(\d+)' or '/shop/(\d+)/sell/(\d+)'

 

So I guess this logic works like that, it expands outward. However I really don't want to overcomplicate things for now and just use includes and if statements. Your arrays are fine though but atm I have problems understanding nested stuff, I will however do it in the future.

 

But would I also be with the same result if I used includes like I described above?

Link to comment
Share on other sites

If all your controllers are named: index.php, start.php, .. then you don't need a front controller as Apache already does all what your front controller would do. The reason there is a front controller in some systems is because something has to translate /foo/bar to (new Foo)->bar(); or foo_bar(); when your controllers however are files, then your front controller is obsolete.

 

Using includes you would center the logic required to redirect the user to the correct page, like when he is not logged in.

Edited by ignace
Link to comment
Share on other sites

If all your controllers are named: index.php, start.php, .. then you don't need a front controller as Apache already does all what your front controller would do. The reason there is a front controller in some systems is because something has to translate /foo/bar to (new Foo)->bar(); or foo_bar(); when your controllers however are files, then your front controller is obsolete.

 

Using includes you would center the logic required to redirect the user to the correct page, like when he is not logged in.

 

Great, I thought something was not right here :) So let me get this, using so called "front controller" in my case doesn't have to do nothing else but "center the logic required to redirect the user to the correct page" ?? Or maybe to make nicer URLs and code editing, since everything will be included from www.index.php/ forward.. It is still a nice practice and a feature to have right?

Edited by Matic
Link to comment
Share on other sites

I think it's important to consider what the modern PHP framework community is doing when it comes to routing and showing the right controller/method or anonymous function. Normally the front controller calls a bootstrap, which is a file or class that does the minimum to set up the application, route the request, and return output that is specific to the request. The request might even return a 404 page not found error.

 

This would be a good read for you:

http://phpmaster.com/autoloading-and-the-psr-0-standard/

 

Consider this is my front controller:

<?php
// No cache headers
header('Expires: Wed, 13 Dec 1972 18:37:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Pragma: no-cache');

require_once 'vendor/autoload.php';

// PATH TO FRONT CONTROLLER (this file)
define( 'FCPATH', __DIR__ . '/' );

// PATH TO HEART PACKAGE
define( 'HPPATH', __DIR__ . '/vendor/heart/' );

// PATH TO APP
define( 'APPPATH', __DIR__ . '/app/' );

require_once 'vendor/heart/config/core.php';

// Start an output buffer, because PHP may not be set up with one.
ob_start();

$app = new \Heart\Lib\Container( $cfg );

// Show memory usage for request on local machine
if( $app['config']->item('mode') == 'local' )
{
    \FB::log( round( memory_get_usage() / 1024 / 1024, 2 ) . 'MB memory allocated to PHP' );
}

// Flush any/all output buffers
while( @ob_end_flush() );

/* End of file /index.php */

So you can see that the routing is not actually done here. This front controller just loads my Container class (which is extending Pimple), and once all DI objects are set THEN routing is done. The router itself is a DI object. This is my own private framework, but if you look at the Silex framework you might see what I'm talking about, since it also uses Pimple and is slightly similar. If your routing needs are super basic, and you pretty much want to rely on your own code for everything else, you might try using Slim . For any of this your are going to need to get Composer up and running on your machine, but that's not that hard to do. The upside to using modern PHP frameworks that use Composer is that you can pull in a lot of existing packages and use them, and you don't have to spend time creating functionality that is complex and could take you many hours to achieve. I know all this might sound like a bit much, but going this route will give you the skills to do what you want to do fast, painless, and in a way that is maintainable by other devs. I'm not a big fan of Laravel, but I think it's something you should look at too, since it does use composer and has it's own built in routing, core classes, helpers, etc etc.

Link to comment
Share on other sites

So let me get this, using so called "front controller" in my case doesn't have to do nothing else but "center the logic required to redirect the user to the correct page" ??

No. It was the answer to your second question.

 

A front controller is the single point of entry to boot your application, in Java this is your main method. In C++ this is main(). In PHP this is index.php (or whatever you set as default). Since files can easily be served by Apache you don't need a front controller as Apache does all your front controller needs. However where your system consists of functions or objects it's not so easy to route a request to an object which is why you use a front controller to do this for you. Thus translating /foo/bar to (new Foo)->bar() or to foo_bar().

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.