.. index:: single: Environments How to Master and Create new Environments ========================================= Every application is the combination of code and a set of configuration that dictates how that code should function. The configuration may define the database being used, whether or not something should be cached, or how verbose logging should be. In Symfony2, the idea of "environments" is the idea that the same codebase can be run using multiple different configurations. For example, the ``dev`` environment should use configuration that makes development easy and friendly, while the ``prod`` environment should use a set of configuration optimized for speed. .. index:: single: Environments; Configuration files Different Environments, Different Configuration Files ----------------------------------------------------- A typical Symfony2 application begins with three environments: ``dev``, ``prod``, and ``test``. As discussed, each "environment" simply represents a way to execute the same codebase with different configuration. It should be no surprise then that each environment loads its own individual configuration file. If you're using the YAML configuration format, the following files are used: * for the ``dev`` environment: ``app/config/config_dev.yml`` * for the ``prod`` environment: ``app/config/config_prod.yml`` * for the ``test`` environment: ``app/config/config_test.yml`` This works via a simple standard that's used by default inside the ``AppKernel`` class: .. code-block:: php // app/AppKernel.php // ... class AppKernel extends Kernel { // ... public function registerContainerConfiguration(LoaderInterface $loader) { $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); } } As you can see, when Symfony2 is loaded, it uses the given environment to determine which configuration file to load. This accomplishes the goal of multiple environments in an elegant, powerful and transparent way. Of course, in reality, each environment differs only somewhat from others. Generally, all environments will share a large base of common configuration. Opening the "dev" configuration file, you can see how this is accomplished easily and transparently: .. configuration-block:: .. code-block:: yaml imports: - { resource: config.yml } # ... .. code-block:: xml .. code-block:: php $loader->import('config.php'); // ... To share common configuration, each environment's configuration file simply first imports from a central configuration file (``config.yml``). The remainder of the file can then deviate from the default configuration by overriding individual parameters. For example, by default, the ``web_profiler`` toolbar is disabled. However, in the ``dev`` environment, the toolbar is activated by modifying the default value in the ``dev`` configuration file: .. configuration-block:: .. code-block:: yaml # app/config/config_dev.yml imports: - { resource: config.yml } web_profiler: toolbar: true # ... .. code-block:: xml .. code-block:: php // app/config/config_dev.php $loader->import('config.php'); $container->loadFromExtension('web_profiler', array( 'toolbar' => true, ..., )); .. index:: single: Environments; Executing different environments Executing an Application in Different Environments -------------------------------------------------- To execute the application in each environment, load up the application using either the ``app.php`` (for the ``prod`` environment) or the ``app_dev.php`` (for the ``dev`` environment) front controller: .. code-block:: text http://localhost/app.php -> *prod* environment http://localhost/app_dev.php -> *dev* environment .. note:: The given URLs assume that your web server is configured to use the ``web/`` directory of the application as its root. Read more in :doc:`Installing Symfony2`. If you open up one of these files, you'll quickly see that the environment used by each is explicitly set: .. code-block:: php :linenos: handle(Request::createFromGlobals())->send(); As you can see, the ``prod`` key specifies that this environment will run in the ``prod`` environment. A Symfony2 application can be executed in any environment by using this code and changing the environment string. .. note:: The ``test`` environment is used when writing functional tests and is not accessible in the browser directly via a front controller. In other words, unlike the other environments, there is no ``app_test.php`` front controller file. .. index:: single: Configuration; Debug mode .. sidebar:: *Debug* Mode Important, but unrelated to the topic of *environments* is the ``false`` key on line 8 of the front controller above. This specifies whether or not the application should run in "debug mode". Regardless of the environment, a Symfony2 application can be run with debug mode set to ``true`` or ``false``. This affects many things in the application, such as whether or not errors should be displayed or if cache files are dynamically rebuilt on each request. Though not a requirement, debug mode is generally set to ``true`` for the ``dev`` and ``test`` environments and ``false`` for the ``prod`` environment. Internally, the value of the debug mode becomes the ``kernel.debug`` parameter used inside the :doc:`service container `. If you look inside the application configuration file, you'll see the parameter used, for example, to turn logging on or off when using the Doctrine DBAL: .. configuration-block:: .. code-block:: yaml doctrine: dbal: logging: "%kernel.debug%" # ... .. code-block:: xml .. code-block:: php $container->loadFromExtension('doctrine', array( 'dbal' => array( 'logging' => '%kernel.debug%', ..., ), ... )); .. index:: single: Environments; Creating a new environment Creating a New Environment -------------------------- By default, a Symfony2 application has three environments that handle most cases. Of course, since an environment is nothing more than a string that corresponds to a set of configuration, creating a new environment is quite easy. Suppose, for example, that before deployment, you need to benchmark your application. One way to benchmark the application is to use near-production settings, but with Symfony2's ``web_profiler`` enabled. This allows Symfony2 to record information about your application while benchmarking. The best way to accomplish this is via a new environment called, for example, ``benchmark``. Start by creating a new configuration file: .. configuration-block:: .. code-block:: yaml # app/config/config_benchmark.yml imports: - { resource: config_prod.yml } framework: profiler: { only_exceptions: false } .. code-block:: xml .. code-block:: php // app/config/config_benchmark.php $loader->import('config_prod.php') $container->loadFromExtension('framework', array( 'profiler' => array('only-exceptions' => false), )); And with this simple addition, the application now supports a new environment called ``benchmark``. This new configuration file imports the configuration from the ``prod`` environment and modifies it. This guarantees that the new environment is identical to the ``prod`` environment, except for any changes explicitly made here. Because you'll want this environment to be accessible via a browser, you should also create a front controller for it. Copy the ``web/app.php`` file to ``web/app_benchmark.php`` and edit the environment to be ``benchmark``: .. code-block:: php handle(Request::createFromGlobals())->send(); The new environment is now accessible via:: http://localhost/app_benchmark.php .. note:: Some environments, like the ``dev`` environment, are never meant to be accessed on any deployed server by the general public. This is because certain environments, for debugging purposes, may give too much information about the application or underlying infrastructure. To be sure these environments aren't accessible, the front controller is usually protected from external IP addresses via the following code at the top of the controller: .. code-block:: php if (!in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) { die('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.'); } .. index:: single: Environments; Cache directory Environments and the Cache Directory ------------------------------------ Symfony2 takes advantage of caching in many ways: the application configuration, routing configuration, Twig templates and more are cached to PHP objects stored in files on the filesystem. By default, these cached files are largely stored in the ``app/cache`` directory. However, each environment caches its own set of files: .. code-block:: text app/cache/dev - cache directory for the *dev* environment app/cache/prod - cache directory for the *prod* environment Sometimes, when debugging, it may be helpful to inspect a cached file to understand how something is working. When doing so, remember to look in the directory of the environment you're using (most commonly ``dev`` while developing and debugging). While it can vary, the ``app/cache/dev`` directory includes the following: * ``appDevDebugProjectContainer.php`` - the cached "service container" that represents the cached application configuration; * ``appdevUrlGenerator.php`` - the PHP class generated from the routing configuration and used when generating URLs; * ``appdevUrlMatcher.php`` - the PHP class used for route matching - look here to see the compiled regular expression logic used to match incoming URLs to different routes; * ``twig/`` - this directory contains all the cached Twig templates. .. note:: You can easily change the directory location and name. For more information read the article :doc:`/cookbook/configuration/override_dir_structure`. Going Further ------------- Read the article on :doc:`/cookbook/configuration/external_parameters`.