|
| 1 | +.. index:: |
| 2 | + single: How front controller, ``AppKernel`` and environments |
| 3 | + work together |
| 4 | + |
| 5 | +Understanding how the Front Controller, Kernel and Environments work together |
| 6 | +============================================================================= |
| 7 | + |
| 8 | +The section :doc:`/cookbook/configuration/environments` explained the basics |
| 9 | +on how Symfony uses environments to run your application with different configuration |
| 10 | +settings. This section will explain a bit more in-depth what happens when |
| 11 | +your application is bootstrapped. To hook into this process, you need to understand |
| 12 | +three parts that work together: |
| 13 | + |
| 14 | +* `The Front Controller`_ |
| 15 | +* `The Kernel Class`_ |
| 16 | +* `The Environments`_ |
| 17 | + |
| 18 | +.. note:: |
| 19 | + |
| 20 | + Usually, you will not need to define your own front controller or |
| 21 | + ``AppKernel`` class as the `Symfony2 Standard Edition`_ provides |
| 22 | + sensible default implementations. |
| 23 | + |
| 24 | + This documentation section is provided to explain what is going on behind |
| 25 | + the scenes. |
| 26 | + |
| 27 | +The Front Controller |
| 28 | +-------------------- |
| 29 | + |
| 30 | +The `front controller`_ is a well-known design pattern; it is a section of |
| 31 | +code that *all* requests served by an application run through. |
| 32 | + |
| 33 | +In the `Symfony2 Standard Edition`_, this role is taken by the `app.php`_ |
| 34 | +and `app_dev.php`_ files in the ``web/`` directory. These are the very |
| 35 | +first PHP scripts executed when a request is processed. |
| 36 | + |
| 37 | +The main purpose of the front controller is to create an instance of the |
| 38 | +``AppKernel`` (more on that in a second), make it handle the request |
| 39 | +and return the resulting response to the browser. |
| 40 | + |
| 41 | +Because every request is routed through it, the front controller can be |
| 42 | +used to perform global initializations prior to setting up the kernel or |
| 43 | +to *`decorate`_* the kernel with additional features. Examples include: |
| 44 | + |
| 45 | +* Configuring the autoloader or adding additional autoloading mechanisms; |
| 46 | +* Adding HTTP level caching by wrapping the kernel with an instance of |
| 47 | + :ref:`AppCache<symfony-gateway-cache>`; |
| 48 | + |
| 49 | +The front controller can be chosen by requesting URLs like: |
| 50 | + |
| 51 | +.. code-block:: text |
| 52 | +
|
| 53 | + http://localhost/app_dev.php/some/path/... |
| 54 | +
|
| 55 | +As you can see, this URL contains the PHP script to be used as the front |
| 56 | +controller. You can use that to easily switch the front controller or use |
| 57 | +a custom one by placing it in the ``web/`` directory (e.g. ``app_cache.php``). |
| 58 | + |
| 59 | +When using Apache and the `RewriteRule shipped with the Standard Edition`_, |
| 60 | +you can omit the filename from the URL and the RewriteRule will use ``app.php`` |
| 61 | +as the default one. |
| 62 | + |
| 63 | +.. note:: |
| 64 | + |
| 65 | + Pretty much every other web server should be able to achieve a |
| 66 | + behavior similar to that of the RewriteRule described above. |
| 67 | + Check your server documentation for details or see |
| 68 | + :doc:`/cookbook/configuration/web_server_configuration`. |
| 69 | + |
| 70 | +.. note:: |
| 71 | + |
| 72 | + Make sure you appropriately secure your front controllers against unauthorized |
| 73 | + access. For example, you don't want to make a debugging environment |
| 74 | + available to arbitrary users in your production environment. |
| 75 | + |
| 76 | +Technically, the `app/console`_ script used when running Symfony on the command |
| 77 | +line is also a front controller, only that is not used for web, but for command |
| 78 | +line requests. |
| 79 | + |
| 80 | +The Kernel Class |
| 81 | +---------------- |
| 82 | + |
| 83 | +The :class:`Symfony\\Component\\HttpKernel\\Kernel` is the core of |
| 84 | +Symfony2. It is responsible for setting up all the bundles that make up |
| 85 | +your application and providing them with the application's configuration. |
| 86 | +It then creates the service container before serving requests in its |
| 87 | +:method:`Symfony\\Component\\HttpKernel\\HttpKernelInterface::handle` |
| 88 | +method. |
| 89 | + |
| 90 | +There are two methods declared in the |
| 91 | +:class:`Symfony\\Component\\HttpKernel\\KernelInterface` that are |
| 92 | +left unimplemented in :class:`Symfony\\Component\\HttpKernel\\Kernel` |
| 93 | +and thus serve as `template methods`_: |
| 94 | + |
| 95 | +* :method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerBundles`, |
| 96 | + which must return an array of all bundles needed to run the |
| 97 | + application; |
| 98 | + |
| 99 | +* :method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerContainerConfiguration`, |
| 100 | + which loads the application configuration. |
| 101 | + |
| 102 | +To fill these (small) blanks, your application needs to subclass the |
| 103 | +Kernel and implement these methods. The resulting class is conventionally |
| 104 | +called the ``AppKernel``. |
| 105 | + |
| 106 | +Again, the Symfony2 Standard Edition provides an `AppKernel`_ in the ``app/`` |
| 107 | +directory. This class uses the name of the environment - which is passed to |
| 108 | +the Kernel's :method:`constructor<Symfony\\Component\\HttpKernel\\Kernel::__construct>` |
| 109 | +method and is available via :method:`Symfony\\Component\\HttpKernel\\Kernel::getEnvironment` - |
| 110 | +to decide which bundles to create. The logic for that is in ``registerBundles()``, |
| 111 | +a method meant to be extended by you when you start adding bundles to your |
| 112 | +application. |
| 113 | + |
| 114 | +You are, of course, free to create your own, alternative or additional |
| 115 | +``AppKernel`` variants. All you need is to adapt your (or add a new) front |
| 116 | +controller to make use of the new kernel. |
| 117 | + |
| 118 | +.. note:: |
| 119 | + |
| 120 | + The name and location of the ``AppKernel`` is not fixed. When |
| 121 | + putting multiple Kernels into a single application, |
| 122 | + it might therefore make sense to add additional sub-directories, |
| 123 | + for example ``app/admin/AdminKernel.php`` and |
| 124 | + ``app/api/ApiKernel.php``. All that matters is that your front |
| 125 | + controller is able to create an instance of the appropriate |
| 126 | + kernel. |
| 127 | + |
| 128 | +Having different ``AppKernels`` might be useful to enable different front |
| 129 | +controllers (on potentially different servers) to run parts of your application |
| 130 | +independently (for example, the admin UI, the frontend UI and database migrations). |
| 131 | + |
| 132 | +.. note:: |
| 133 | + |
| 134 | + There's a lot more the ``AppKernel`` can be used for, for example |
| 135 | + :doc:`overriding the default directory structure </cookbook/configuration/override_dir_structure>`. |
| 136 | + But odds are high that you don't need to change things like this on the |
| 137 | + fly by having several ``AppKernel`` implementations. |
| 138 | + |
| 139 | +The Environments |
| 140 | +---------------- |
| 141 | + |
| 142 | +We just mentioned another method the ``AppKernel`` has to implement - |
| 143 | +:method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerContainerConfiguration`. |
| 144 | +This method is responsible for loading the application's |
| 145 | +configuration from the right *environment*. |
| 146 | + |
| 147 | +Environments have been covered extensively |
| 148 | +:doc:`in the previous chapter</cookbook/configuration/environments>`, |
| 149 | +and you probably remember that the Standard Edition comes with three |
| 150 | +of them - ``dev``, ``prod`` and ``test``. |
| 151 | + |
| 152 | +More technically, these names are nothing more than strings passed from the |
| 153 | +front controller to the ``AppKernel``'s constructor. This name can then be |
| 154 | +used in the :method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerContainerConfiguration` |
| 155 | +method to decide which configuration files to load. |
| 156 | + |
| 157 | +The Standard Edition's `AppKernel`_ class implements this method by simply |
| 158 | +loading the ``app/config/config_*environment*.yml`` file. You are, of course, |
| 159 | +free to implement this method differently if you need a more sophisticated |
| 160 | +way of loading your configuration. |
| 161 | + |
| 162 | +.. _front controller: http://en.wikipedia.org/wiki/Front_Controller_pattern |
| 163 | +.. _Symfony2 Standard Edition: https://github.com/symfony/symfony-standard |
| 164 | +.. _app.php: https://github.com/symfony/symfony-standard/blob/master/web/app.php |
| 165 | +.. _app_dev.php: https://github.com/symfony/symfony-standard/blob/master/web/app_dev.php |
| 166 | +.. _app/console: https://github.com/symfony/symfony-standard/blob/master/app/console |
| 167 | +.. _AppKernel: https://github.com/symfony/symfony-standard/blob/master/app/AppKernel.php |
| 168 | +.. _decorate: http://en.wikipedia.org/wiki/Decorator_pattern |
| 169 | +.. _RewriteRule shipped with the Standard Edition: https://github.com/symfony/symfony-standard/blob/master/web/.htaccess) |
| 170 | +.. _template methods: http://en.wikipedia.org/wiki/Template_method_pattern |
0 commit comments