diff --git a/configuration/configuration_organization.rst b/configuration/configuration_organization.rst index 5c22dfc2572..2bb3cbba181 100644 --- a/configuration/configuration_organization.rst +++ b/configuration/configuration_organization.rst @@ -4,10 +4,9 @@ How to Organize Configuration Files =================================== -The default Symfony Standard Edition defines three -:doc:`execution environments ` called -``dev``, ``prod`` and ``test``. An environment simply represents a way to -execute the same codebase with different configurations. +The Symfony skeleton defines three :doc:`execution environments ` +called ``dev``, ``prod`` and ``test``. An environment simply represents a way +to execute the same codebase with different configurations. In order to select the configuration file to load for each environment, Symfony executes the ``registerContainerConfiguration()`` method of the ``AppKernel`` @@ -17,7 +16,7 @@ class:: use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Config\Loader\LoaderInterface; - class AppKernel extends Kernel + class Kernel extends BaseKernel { // ... diff --git a/configuration/environments.rst b/configuration/environments.rst index c90657f630f..df77a79b73d 100644 --- a/configuration/environments.rst +++ b/configuration/environments.rst @@ -20,128 +20,58 @@ Different Environments, different Configuration Files ----------------------------------------------------- A typical Symfony application begins with three environments: ``dev``, -``prod``, and ``test``. As mentioned, 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: +``prod`` and ``test``. As mentioned, each environment 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 +files. These different files are organized by environment: -* 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`` +* for the ``dev`` environment: ``config/packages/dev/`` +* for the ``prod`` environment: ``config/packages/prod/`` +* for the ``test`` environment: ``config/packages/test/`` -This works via a simple standard that's used by default inside the ``AppKernel`` -class: +In reality, each environment differs only somewhat from others. This means that +all environments share a large base of common configurations. This configuration +is put in files directly in the ``config/packages/`` directory. -.. code-block:: php +The location of these files is defined by the application's Kernel:: - // app/AppKernel.php + // src/Kernel.php // ... - - class AppKernel extends Kernel + class Kernel extends BaseKernel { // ... - public function registerContainerConfiguration(LoaderInterface $loader) + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader) { - $loader->load($this->getProjectDir().'/app/config/config_'.$this->getEnvironment().'.yml'); - } - } - -As you can see, when Symfony 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 ``config_dev.yml`` 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 value of the ``toolbar`` option in the ``config_dev.yml`` -configuration file: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/config_dev.yml - imports: - - { resource: config.yml } - - web_profiler: - toolbar: true - # ... - - .. code-block:: xml - - - - - - - - + // ... + $confDir = $this->getProjectDir().'/config'; - + // always load all files in /config/packages/ + $loader->load($confDir.'/packages/*'.self::CONFIG_EXTS, 'glob'); - + // then, if available, load the files in the specific environment directory + if (is_dir($confDir.'/packages/'.$this->environment)) { + $loader->load($confDir.'/packages/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); + } - .. code-block:: php - - // app/config/config_dev.php - $loader->import('config.php'); + // load a special services.(yaml/xml/php) and, if available, services_ENVIRONMENT.(yaml/xml/php) file + $loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob'); + } + } - $container->loadFromExtension('web_profiler', array( - 'toolbar' => true, +Take the framework package, installed by default, as an example: - // ... - )); +* Loaded in all environments, ``config/packages/framework.yaml`` configures the + framework with some ``secret`` setting; +* In the **prod** environment, nothing extra will be set as there is no + ``config/packages/prod/`` directory; +* The same applies to **dev**, as there is no + ``config/packages/framework.yaml``. There are however other packages (e.g. + ``routing.yaml``) with special dev settings; +* At last, during the **test** environment, the framework's test features are + enabled in ``config/packages/test/framework.yaml``. .. index:: single: Environments; Executing different environments @@ -149,77 +79,77 @@ configuration file: Executing an Application in different Environments -------------------------------------------------- -To execute the application in each environment, load up the application using -either ``app.php`` (for the ``prod`` environment) or ``app_dev.php`` -(for the ``dev`` environment) front controller: +To execute the application in each environment, change the ``APP_ENV`` +environment variable. During development, this is done in ``.env``: -.. code-block:: text +.. code-block:: bash + + # .env + APP_ENV=dev + + # or for test: + #APP_ENV=test - http://localhost/app.php -> *prod* environment - http://localhost/app_dev.php -> *dev* environment +Visit the ``http://localhost:8000/index.php`` page in your web browser to see +your application in the configured environment. -If you don't have *either* filename in your URL, then it's up to your web server -to decide *which* file to execute behind the scenes. If you're using the built-in -PHP web server, it knows to use the ``app_dev.php`` file. On production, you'll -:doc:`configure your web server ` to use ``app.php``. -Either way: *one of these two files is always executed*. +.. tip:: + + In production, it is recommended to configure the environment variables in + your :ref:`web server configuration `. .. 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 Symfony `. + The given URLs assume that your web server is configured to use the ``public/`` + directory of the application as its root. Read more in :doc:`Installing Symfony `. -If you open up one of these files, you'll quickly see that the environment -used by each is explicitly set:: +If you open the file you just visited (``public/index.php``), you'll see that +the environment variable is passed to the kernel:: - // web/app.php - // ... + // public/index.php - $kernel = new AppKernel('prod', false); + // ... + $kernel = new Kernel($_SERVER['APP_ENV'] ?? 'dev', $_SERVER['APP_DEBUG'] ?? false); // ... -The ``prod`` key specifies that this application will run in the ``prod`` -environment. A Symfony application can be executed in any environment by using -this code and changing the environment string. +You can also replace ``$_SERVER['APP_ENV'] ?? 'dev'`` by just ``'dev'`` to +always run the application in the dev environment, independent of the +``APP_ENV`` variable. .. 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. + usually not accessed in the browser directly via a front controller. .. index:: single: Configuration; Debug mode .. sidebar:: *Debug* Mode - Important, but unrelated to the topic of *environments* is the ``false`` - argument as the second argument to the ``AppKernel`` constructor. This - specifies if the application should run in "debug mode". Regardless - of the environment, a Symfony application can be run with debug mode - set to ``true`` or ``false``. This affects many things in the application, - such as displaying stacktraces on error pages 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. + Important, but unrelated to the topic of *environments* is the second + argument to the ``Kernel`` constructor. This specifies if the application + should run in "debug mode". Regardless of the environment, a Symfony + application can be run with debug mode set to ``true`` or ``false`` + (respectively ``1`` or ``0`` for the ``APP_ENV`` variable defined in + ``.env``). This affects many things in the application, such as displaying + stacktraces on error pages 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: + parameter used, for example, to turn Twig's debug mode on: .. configuration-block:: .. code-block:: yaml - doctrine: - dbal: - logging: '%kernel.debug%' - # ... + # config/packages/twig.yaml + twig: + debug: '%kernel.debug%' .. code-block:: xml @@ -229,20 +159,17 @@ this code and changing the environment string. xmlns:doctrine="http://symfony.com/schema/dic/doctrine" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd - http://symfony.com/schema/dic/doctrine - http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd"> + http://symfony.com/schema/dic/twig + http://symfony.com/schema/dic/twig/twig-1.0.xsd"> - + .. code-block:: php - $container->loadFromExtension('doctrine', array( - 'dbal' => array( - 'logging' => '%kernel.debug%', - // ... - ), + $container->loadFromExtension('twig', array( + 'debug' => '%kernel.debug%', // ... )); @@ -265,15 +192,8 @@ behavior: $ php bin/console command_name --env=test --no-debug In addition to the ``--env`` and ``--no-debug`` options, the behavior of Symfony -commands can also be controlled with environment variables. The Symfony console -application checks the existence and value of these environment variables before -executing any command: - -``SYMFONY_ENV`` - Sets the execution environment of the command to the value of this variable - (``dev``, ``prod``, ``test``, etc.); -``SYMFONY_DEBUG`` - If ``0``, debug mode is disabled. Otherwise, debug mode is enabled. +commands can also be controlled with the same environment variables used by +``public/index.php``. These environment variables are very useful for production servers because they allow you to ensure that commands always run in the ``prod`` environment without @@ -285,10 +205,8 @@ having to add any command option. Creating a new Environment -------------------------- -By default, a Symfony 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. +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 @@ -296,22 +214,20 @@ settings, but with Symfony's ``web_profiler`` enabled. This allows Symfony 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: +``benchmark``. Start by creating a new configuration directory and a +configuration file: .. configuration-block:: .. code-block:: yaml - # app/config/config_benchmark.yml - imports: - - { resource: config_prod.yml } - + # config/packages/benchmark/web_profiler.yaml framework: profiler: { only_exceptions: false } .. code-block:: xml - + - - - - @@ -333,50 +245,77 @@ The best way to accomplish this is via a new environment called, for example, .. code-block:: php - // app/config/config_benchmark.php - $loader->import('config_prod.php'); - + // config/packages/benchmark/web_profiler.php $container->loadFromExtension('framework', array( 'profiler' => array('only_exceptions' => false), )); -.. include:: /components/dependency_injection/_imports-parameters-note.rst.inc +And... you're finished! The application now supports a new environment called +``benchmark``. -And with this simple addition, the application now supports a new environment -called ``benchmark``. +Change the ``APP_ENV`` variable to ``benchmark`` to be able to access the new +environment through your browser: -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. +.. code-block:: bash -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``:: + # .env + APP_ENV=benchmark - // web/app_benchmark.php - // ... +.. sidebar:: Importing configuration - // change just this line - $kernel = new AppKernel('benchmark', false); + Besides loading files in the Kernel, you can also import files in the + configuration directly. For instance, to make sure the benchmark + environment is identical to the prod environment, you might want to load + all its configuration as well. - // ... + You can achieve this by using a special ``imports`` key: -The new environment is now accessible via:: + .. configuration-block: - http://localhost/app_benchmark.php + .. code-block:: yaml -.. note:: + # config/packages/benchmark/other.yaml + imports: + - { resource: '../prod/' } - Some environments, like the ``dev`` environment, are never meant to be - accessed on any deployed server by the 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:: + # other resources are possible as well, like importing other + # files or using globs: + #- { resource: '/etc/myapp/some_special_config.xml' } + #- { resource: '/etc/myapp/*.yaml' } - 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.'); - } + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // config/packages/benchmark/other.php + $loader->import('../prod/'); + + // other resources are possible as well, like importing other + // files or using globs: + //$loader->import('/etc/myapp/some_special_config.yaml'); + //$loader->import('/etc/myapp/*.php'); .. index:: single: Environments; Cache directory @@ -388,7 +327,7 @@ Symfony 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 ``var/cache`` directory. +By default, these cached files are largely stored in the ``var/cache/`` directory. However, each environment caches its own set of files: .. code-block:: text @@ -402,8 +341,8 @@ However, each environment caches its own set of files: 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 ``var/cache/dev`` directory +the directory of the environment you're using (most commonly ``dev/`` while +developing and debugging). While it can vary, the ``var/cache/dev/`` directory includes the following: ``appDevDebugProjectContainer.php`` diff --git a/configuration/external_parameters.rst b/configuration/external_parameters.rst index 8788cb4c47c..a052cacd1e9 100644 --- a/configuration/external_parameters.rst +++ b/configuration/external_parameters.rst @@ -4,7 +4,7 @@ How to Set external Parameters in the Service Container ======================================================= -In the article :doc:`/configuration`, you learned how to manage your application +In :doc:`/configuration`, you learned how to manage your application configuration. At times, it may benefit your application to store certain credentials outside of your project code. Database configuration is one such example. The flexibility of the Symfony service container allows you to easily @@ -18,22 +18,30 @@ the variables you want to use enclosed between ``env()``. Their actual values will be resolved at runtime (once per request), so that dumped containers can be reconfigured dynamically even after being compiled. -For example, if you want to use the value of the ``DATABASE_HOST`` environment -variable in your service container configuration, you can reference it using -``%env(DATABASE_HOST)%`` in your configuration files: +For example, when installing the ``doctrine`` recipe, database configuration is +put in a ``DATABASE_URL`` environment variable: + +.. code-block:: bash + + # .env + DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?charset=utf8mb4&serverVersion=5.7" + +This variable is referenced in the service container configuration using +``%env(DATABASE_HOST)%``: .. configuration-block:: .. code-block:: yaml - # app/config/config.yml + # config/packages/doctrine.yaml doctrine: dbal: - host: '%env(DATABASE_HOST)%' + url: '%env(DATABASE_URL)%' + # ... .. code-block:: xml - + @@ -53,10 +61,10 @@ variable in your service container configuration, you can reference it using .. code-block:: php - // app/config/config.php + // config/packages/doctrine.php $container->loadFromExtension('doctrine', array( 'dbal' => array( - 'host' => '%env(DATABASE_HOST)%', + 'url' => '%env(DATABASE_URL)%', ) )); @@ -67,34 +75,37 @@ will be used whenever the corresponding environment variable is *not* found: .. code-block:: yaml - # app/config/parameters.yml + # config/services.yaml parameters: - database_host: '%env(DATABASE_HOST)%' env(DATABASE_HOST): localhost .. code-block:: xml - + - %env(DATABASE_HOST)% localhost .. code-block:: php - // app/config/parameters.php - $container->setParameter('database_host', '%env(DATABASE_HOST)%'); + // config/services.php $container->setParameter('env(DATABASE_HOST)', 'localhost'); -Setting environment variables is generally done at the web server level or in the -terminal. If you're using Apache, Nginx or just the console, you can use e.g. one -of the following: +.. _configuration-env-var-in-prod: + +Configuring Environment Variables in Production +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +During development, you'll use the ``.env`` file to configure your environment +variables. On your production server, it is recommended to configure these at +the web server level. If you're using Apache or Nginx, you can use e.g. one of +the following: .. configuration-block:: @@ -103,19 +114,12 @@ of the following: # ... - SetEnv DATABASE_USER user - SetEnv DATABASE_PASSWORD secret + SetEnv DATABASE_URL "mysql://db_user:db_password@127.0.0.1:3306/db_name?charset=utf8mb4&serverVersion=5.7" .. code-block:: nginx - fastcgi_param DATABASE_USER user; - fastcgi_param DATABASE_PASSWORD secret; - - .. code-block:: terminal - - $ export DATABASE_USER=user - $ export DATABASE_PASSWORD=secret + fastcgi_param DATABASE_URL "mysql://db_user:db_password@127.0.0.1:3306/db_name?charset=utf8mb4&serverVersion=5.7"; .. tip:: @@ -135,53 +139,19 @@ See :ref:`component-di-parameters-constants` for more details. Miscellaneous Configuration --------------------------- -The ``imports`` directive can be used to pull in parameters stored elsewhere. -Importing a PHP file gives you the flexibility to add whatever is needed -in the container. The following imports a file named ``parameters.php``. - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/config.yml - imports: - - { resource: parameters.php } - - .. code-block:: xml - - - - - - - - +You can mix whatever configuration format you like (YAML, XML and PHP) in +``config/packages/``. Importing a PHP file gives you the flexibility to add +whatever is needed in the container. For instance, you can create a +``drupal.php`` file in which you set a database URL based on Drupal's database +configuration:: - + // config/packages/drupal.php - .. code-block:: php - - // app/config/config.php - $loader->import('parameters.php'); - -.. note:: - - A resource file can be one of many types. PHP, XML, YAML, INI, and - closure resources are all supported by the ``imports`` directive. - -In ``parameters.php``, tell the service container the parameters that you wish -to set. This is useful when important configuration is in a non-standard -format. The example below includes a Drupal database configuration in -the Symfony service container. - -.. code-block:: php - - // app/config/parameters.php + // import Drupal's configuration include_once('/path/to/drupal/sites/default/settings.php'); - $container->setParameter('drupal.database.url', $db_url); + + // set a app.database_url parameter + $container->setParameter('app.database_url', $db_url); .. _`SetEnv`: http://httpd.apache.org/docs/current/env.html .. _`fastcgi_param`: http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param diff --git a/configuration/front_controllers_and_kernel.rst b/configuration/front_controllers_and_kernel.rst index 54cab74072a..a5160a47108 100644 --- a/configuration/front_controllers_and_kernel.rst +++ b/configuration/front_controllers_and_kernel.rst @@ -27,16 +27,16 @@ three parts that work together: The Front Controller -------------------- -The `front controller`_ is a well-known design pattern; it is a section of -code that *all* requests served by an application run through. +The `front controller`_ is a design pattern; it is a section of code that *all* +requests served by an application run through. -In the `Symfony Standard Edition`_, this role is taken by the `index.php`_ file -in the ``public/`` directory. This is the very first PHP script executed when a +In the Symfony Skeleton, this role is taken by the `index.php`_ file in the +``public/`` directory. This is the very first PHP script executed when a request is processed. The main purpose of the front controller is to create an instance of the -``AppKernel`` (more on that in a second), make it handle the request -and return the resulting response to the browser. +``Kernel`` (more on that in a second), make it handle the request and return +the resulting response to the browser. Because every request is routed through it, the front controller can be used to perform global initialization prior to setting up the kernel or @@ -47,33 +47,23 @@ to `decorate`_ the kernel with additional features. Examples include: :ref:`AppCache `; * Enabling the :doc:`Debug Component `. -The front controller can be chosen by requesting URLs like: +You can choose the front controller that's used by adding it in the URL, like: .. code-block:: text - http://localhost/app_dev.php/some/path/... + http://localhost/index.php/some/path/... As you can see, this URL contains the PHP script to be used as the front -controller. You can use that to easily switch the front controller or use -a custom one by placing it in the ``web/`` directory (e.g. ``app_cache.php``). +controller. You can use that to easily switch to a custom made front controller +that is located in the ``public/`` directory or e.g. access the ``check.php`` +file. -When using Apache and the `RewriteRule shipped with the Symfony Standard Edition`_, -you can omit the filename from the URL and the RewriteRule will use ``app.php`` -as the default one. +.. seealso:: -.. note:: - - Pretty much every other web server should be able to achieve a - behavior similar to that of the RewriteRule described above. - Check your server documentation for details or see + You almost never want to show the front controller in the URL. This is + achieved by configuring the web server, as shown in :doc:`/setup/web_server_configuration`. -.. note:: - - Make sure you appropriately secure your front controllers against unauthorized - access. For example, you don't want to make a debugging environment - available to arbitrary users in your production environment. - Technically, the `bin/console`_ script used when running Symfony on the command line is also a front controller, only that is not used for web, but for command line requests. @@ -164,5 +154,4 @@ way of loading your configuration. .. _bin/console: https://github.com/symfony/symfony-standard/blob/master/bin/console .. _AppKernel: https://github.com/symfony/symfony-standard/blob/master/app/AppKernel.php .. _decorate: https://en.wikipedia.org/wiki/Decorator_pattern -.. _RewriteRule shipped with the Symfony Standard Edition: https://github.com/symfony/symfony-standard/blob/master/web/.htaccess .. _template methods: https://en.wikipedia.org/wiki/Template_method_pattern