6

For a PHP MVC application, what is the difference of the job of the index.php file and front-controller? Is the front-controller in the index.php, or is it in a separate file? How do I separate the two and let them work together? Is the front-controller supposed to be a class (or like its own entity)? (If that's the case, then index.php will instantiate the front-controller?)

I know that they have to "set up the environment," which includes defining some constants and etc, but what does what? (-- autoloader, debug stuff, etc.)

I have seen this: MVC with a front controller confusion, but that doesn't solve the problem of the difference between index.php and the front-controller.

Community
  • 1
  • 1
  • This answer is too short to be posted as an answer. You really should read up on the structure of MVC, specifically when used with PHP. Initialize an instance of `front-controller` in `index.php`, end of story. – AndreasHassing Nov 29 '13 at 01:39
  • so you're saying that all `index.php` does is to initialize the `front-controller`? –  Nov 29 '13 at 01:41
  • Yep, that's exactly what I'm saying. What do you want it to do more than that? If your `front-controller` is good and done, it should work as intended, and render your page once the constructor has finished. – AndreasHassing Nov 29 '13 at 01:46
  • @Andreas Bjørn thanks, and since that was all I was asking, it isn't too short to be posted as an answer –  Nov 29 '13 at 01:51
  • In that case I'll post it as an answer. – AndreasHassing Nov 29 '13 at 01:56

3 Answers3

20

Actually, index.php should not contain any meaningful code at all, since it would be only part of your site, that is located inside DOCUMENT_ROOT of webserver. It's content should actually look something like:

<?php 

    require '../application/bootstrap.php';

It should only include a file outside DOCUMENT_ROOT. And that's all.

This way, if something goes horribly wrong (like, php extension fails after server update) and visitors are exposed to raw php code, it will not reveal any sensitive details.

The point of Front Controller is handle all user input, turn it into a consumable form and, based on it, dispatch a command (usually in a form of method call on an object). In languages like Java, where everything must be contained in a class, a front controller would be a class. But in php you do not have this restriction.

Instead the front controller will end up being part of your bootstrap stage of the application:

// --- snip --- 
// the autoloader has been initialized already a bit earlier

$router = new Router;
$router->loadConfig($configuration);

$request = new Request;
$request->setUri($GET['url']); 
// could also be $_SERVER['PATH_INFO'] or other
// depends on how url rewrite is set up

$router->route($request);
// the request instance is populated with data from first matching route

$class = $request->getParameter('resource');
$command = $request->getMethod() . $request->getParameter('action');

if (class_exists($class)) {
    $instance = new $class;
    $instance->{$command}($request);
    // you dispatch to the proper class's method 
}

// --- snip --- 
// then there will be some other code, unrelated to front controller

Also, you should keep in mind that concept of front controller is neither made-for nor demanded-by application that attempt to implement MVC or MVC-inspired architecture.

tereško
  • 58,060
  • 25
  • 98
  • 150
  • Wow! you made it so ***clear*** to me! **Very** good answer and thank you! –  Nov 30 '13 at 22:06
  • In that case why not have .htaccess forward all requests to the bootstrap script and do away with index.php? – davidfurber Dec 01 '13 at 01:58
  • 2
    davidfurber, I am not a 100% sure of this but I don't think that the webserver will be able to access files outside of the designated folder. Otherwise it seems to me it would be a pretty big security concern. The idea is to have the webserver call the index.php and then PHP can take it from there and access whatever it needs to. – Patrick Dec 01 '13 at 18:17
  • @davidfurber , then, if `mod_php` fails to load, you will be seeing the `bootstrap.php` file, instead of index. Which would bring you back to square nr.1 – tereško Dec 01 '13 at 18:35
  • Maybe splitting hairs but if the bootstrap was a symlink and htaccess only allowed to follow symlinks if mod_php and mod_rewrite were loaded... In practice, I see that CakePHP puts the front controller in the index.php file in the webroot, so it suffers if mod_php fails to load. Yii loads the config and passes it to Yii::createWebApplication. Symfony does the same but with different flavor. CodeIgniter does an extended configuration in index.php before requiring its front controller. So Yii gives away the least, CakePHP the most. – davidfurber Dec 01 '13 at 19:32
  • Man, I've been looking left and right and trying so many things in order to set up the DOCUMENT_ROOT you mention in a dynamic manner but I've had no luck. http://stackoverflow.com/questions/35198934/how-can-the-document-root-request-location-be-changed-in-http-server-behavior I even made this topic about it but still nothing. It would be nice if you could help. – Dante Feb 08 '16 at 19:59
  • @Dante ping me in php chat room and I will try to explain it to you: https://chat.stackoverflow.com/rooms/11/php – tereško Feb 13 '16 at 12:09
  • some framework like codeigniter do many things in index.php like switching between enviroment https://github.com/bcit-ci/CodeIgniter/blob/develop/index.php so this is bad pratice or should i do these things in bootstrap.php? – Linus Aug 09 '16 at 06:51
  • 1
    @Linus only things done in that file are definitions of various "path constants". I personally **would describe it** as bad practice because of two reasons. I case of `mod_php` (or on of its alternative), this would leak at least partial knowledge about directory structure of your application. The other issue is to do with constants themselves - they introduce immutable global state. Which means that some class somewhere in your code is using information that you did not give it. And you have no idea where and how, – tereško Aug 09 '16 at 08:31
  • @tereško so how would you prefer to do it? – Linus Aug 09 '16 at 08:33
  • Do what? What you are asking me actually boils down to: "how do you pass configuration without using global variables?" ... and you should be able to answer that yourself. – tereško Aug 09 '16 at 08:37
  • btw Thanks will do it :) – Linus Aug 09 '16 at 08:44
4

Index.php should initialize the application and call something that deciphers the route into controller and action, and runs them. Look at Yii, Symfony, CodeIgniter, CakePHP, see what they do. All slightly different but same principle.

An example from Yii's index.php to make the point:

<?php

$yii=dirname(__FILE__).'/../../framework/yii.php';
$config=dirname(__FILE__).'/protected/config/main.php';
require_once($yii);
Yii::createWebApplication($config)->run();

$config gets passed to the web application, which serves as the front controller.

davidfurber
  • 5,274
  • 1
  • 20
  • 11
  • to what extent do you mean by initialize? –  Nov 29 '13 at 01:53
  • For example I have a Yii application in which I have extended/customized the initializing based on if it's a web request or console request, test, dev, or production environment. So the relevant index.php sets some constants, loads an initializer class, then loads the relevant Yii application class, passes the configuration, and runs it. That's it. – davidfurber Nov 29 '13 at 02:01
  • what is the difference, in this case, then, between the `index.php` and the front-controller? –  Nov 29 '13 at 02:35
  • and what does the front-controller do then? –  Nov 29 '13 at 02:50
  • Index.php is a simple script that initialized and runs the front controller, which is encapsulated in a separate class and file(s). If you're rolling your own, you could, I suppose, you could start writing your front controller code in index.php, but it soon grows too complex. – davidfurber Nov 29 '13 at 02:51
  • 1
    The front controller determines which controller and action to call based on the URL. It builds a request and passes it along to the controller. It could also receive the rendered response and perform additional work. I agree with Andreas that you should read up on MVC in PHP, and take a look at the various frameworks. One design goal in PHP, for example, is to minimize the amount of framework code you have to load, because it has to be loaded with each request. – davidfurber Nov 29 '13 at 02:57
  • you aren't making it clear to me. You said "Index.php should initialize the application and call something that deciphers the route into controller and action, and runs them." and "The front controller determines which controller and action to call based on the URL. It builds a request and passes it along to the controller." What does the routing? –  Nov 29 '13 at 03:03
  • This is what I'm thinking of: https://github.com/yiisoft/yii/blob/master/demos/blog/index.php . It is the index.php of yii. It loads $config (which happens to contain routes, db config, etc) and passes it to CWebApplication, and calls run(). That's it. – davidfurber Nov 29 '13 at 03:06
  • 1
    @jasonszhao Come on, we already told you what to do next, read, learn and prosper. You just EXPLAINED to me 10 minutes ago what routing does, how can you then ask David what it does? There's no easy path to victory my friend, you have to work for it. – AndreasHassing Nov 29 '13 at 03:07
  • im not asking what it does; I was asking for clarification on what David said. At first Andreas and I both thought that David said to let `index.php` do the routing, but then he told us the front-controller did, which was then clarified by the code example. Thanks to both of you, who made really good answers. (im having a hard time deciding which one is accepted) –  Nov 29 '13 at 03:18
1

You really should read up on the structure of MVC, specifically when used with PHP. Initialize an instance of front-controller in index.php, and it should render your page if that process is part of the front-controller initialization procedure (__constructor()).

AndreasHassing
  • 687
  • 4
  • 19
  • 1)I think that dialogue is really unnecessary –  Nov 29 '13 at 02:38
  • 2) Your answer completely contradicts davidfurber's , so I'll wait up before deciding which one is accepted –  Nov 29 '13 at 02:39
  • 1) Alright, fixed the answer to your liking. 2) My answer does not contradict @davidfurber 's - he just seems to believe that routes should be defined in the index-file, whereas I do not. Probably a matter of preference. 3) If you do not know what routes are, you should read up on using PHP and MVC, since it's out of the scope of your question. – AndreasHassing Nov 29 '13 at 02:45
  • it means to process the request (mainly the URI) and include appropriate files, especially the controller –  Nov 29 '13 at 02:53
  • 1
    I wasn't suggesting to define routes in index.php, only that index.php loads an initializer that it then passes to the front controller. https://github.com/yiisoft/yii/blob/master/demos/blog/index.php – davidfurber Nov 29 '13 at 03:03