Matic Posted August 13, 2013 Share Posted August 13, 2013 (edited) 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 August 13, 2013 by Matic Quote Link to comment Share on other sites More sharing options...
kicken Posted August 13, 2013 Share Posted August 13, 2013 (edited) 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 August 13, 2013 by kicken Quote Link to comment Share on other sites More sharing options...
Matic Posted August 13, 2013 Author Share Posted August 13, 2013 (edited) 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 August 13, 2013 by Matic Quote Link to comment Share on other sites More sharing options...
kicken Posted August 13, 2013 Share Posted August 13, 2013 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+)' Quote Link to comment Share on other sites More sharing options...
Matic Posted August 13, 2013 Author Share Posted August 13, 2013 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? Quote Link to comment Share on other sites More sharing options...
ignace Posted August 13, 2013 Share Posted August 13, 2013 (edited) 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 August 13, 2013 by ignace Quote Link to comment Share on other sites More sharing options...
Matic Posted August 13, 2013 Author Share Posted August 13, 2013 (edited) 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 August 13, 2013 by Matic Quote Link to comment Share on other sites More sharing options...
sKunKbad Posted August 14, 2013 Share Posted August 14, 2013 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. Quote Link to comment Share on other sites More sharing options...
ignace Posted August 14, 2013 Share Posted August 14, 2013 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(). Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.