Configuring Symfony ¶
Configuration Files ¶
Symfony applications are configured with the files stored in the config/
directory, which has this default structure:
1 2 3 4 5 6 7 |
your-project/
├─ config/
│ ├─ packages/
│ ├─ bundles.php
│ ├─ routes.yaml
│ └─ services.yaml
├─ ...
|
The routes.yaml
file defines the routing configuration;
the services.yaml
file configures the services of the
service container; the bundles.php
file enables/
disables packages in your application.
You'll be working mostly in the config/packages/
directory. This directory
stores the configuration of every package installed in your application.
Packages (also called "bundles" in Symfony and "plugins/modules" in other
projects) add ready-to-use features to your projects.
When using Symfony Flex, which is enabled by default in
Symfony applications, packages update the bundles.php
file and create new
files in config/packages/
automatically during their installation. For
example, this is the default file created by the "API Platform" package:
1 2 3 4 |
# config/packages/api_platform.yaml
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
|
Splitting the configuration into lots of small files is intimidating for some Symfony newcomers. However, you'll get used to them quickly and you rarely need to change these files after package installation
Tip
To learn about all the available configuration options, check out the
Symfony Configuration Reference or run the
config:dump-reference
command.
Configuration Formats ¶
Unlike other frameworks, Symfony doesn't impose a specific format on you to configure your applications. Symfony lets you choose between YAML, XML and PHP and throughout the Symfony documentation, all configuration examples will be shown in these three formats.
There isn't any practical difference between formats. In fact, Symfony transforms and caches all of them into PHP before running the application, so there's not even any performance difference between them.
YAML is used by default when installing packages because it's concise and very readable. These are the main advantages and disadvantages of each format:
- YAML: simple, clean and readable, but not all IDEs support autocompletion
and validation for it. Learn the YAML syntax;YAML: シンプルでクリーンで読みやすいですが、すべての IDE が自動補完と検証をサポートしているわけではありません。 YAML 構文を学びます。
- XML: autocompleted/validated by most IDEs and is parsed natively by PHP,
but sometimes it generates configuration considered too verbose. Learn the XML syntax;XML: ほとんどの IDE でオートコンプリート/検証され、PHP によってネイティブに解析されますが、冗長すぎると見なされる構成が生成されることがあります。 XML 構文を学びます。
- PHP: very powerful and it allows you to create dynamic configuration with
arrays or a ConfigBuilder.PHP: 非常に強力で、配列または ConfigBuilder を使用して動的構成を作成できます。
Note
By default Symfony loads the configuration files defined in YAML and PHP
formats. If you define configuration in XML format, update the
src/Kernel.php
file to add support for the .xml
file extension.
6.1
The automatic loading of PHP configuration files was introduced in Symfony 6.1.
Importing Configuration Files ¶
Symfony loads configuration files using the Config component, which provides advanced features such as importing other configuration files, even if they use a different format:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# config/services.yaml
imports:
- { resource: 'legacy_config.php' }
# glob expressions are also supported to load multiple files
- { resource: '/etc/myapp/*.yaml' }
# ignore_errors: not_found silently discards errors if the loaded file doesn't exist
- { resource: 'my_config_file.xml', ignore_errors: not_found }
# ignore_errors: true silently discards all errors (including invalid code and not found)
- { resource: 'my_other_config_file.xml', ignore_errors: true }
# ...
|
Configuration Parameters ¶
Sometimes the same configuration value is used in several configuration files.
Instead of repeating it, you can define it as a "parameter", which is like a
reusable configuration value. By convention, parameters are defined under the
parameters
key in the config/services.yaml
file:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# config/services.yaml
parameters:
# the parameter name is an arbitrary string (the 'app.' prefix is recommended
# to better differentiate your parameters from Symfony parameters).
app.admin_email: 'something@example.com'
# boolean parameters
app.enable_v2_protocol: true
# array/collection parameters
app.supported_locales: ['en', 'es', 'fr']
# binary content parameters (encode the contents with base64_encode())
app.some_parameter: !!binary VGhpcyBpcyBhIEJlbGwgY2hhciAH
# PHP constants as parameter values
app.some_constant: !php/const GLOBAL_CONSTANT
app.another_constant: !php/const App\Entity\BlogPost::MAX_ITEMS
# ...
|
Caution
When using XML configuration, the values between <parameter>
tags are
not trimmed. This means that the value of the following parameter will be
'\n something@example.com\n'
:
1 2 3 |
<parameter key="app.admin_email">
something@example.com
</parameter>
|
Once defined, you can reference this parameter value from any other
configuration file using a special syntax: wrap the parameter name in two %
(e.g. %app.admin_email%
):
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 |
# config/packages/some_package.yaml
some_package:
# any string surrounded by two % is replaced by that parameter value
email_address: '%app.admin_email%'
# ...
|
Note
If some parameter value includes the %
character, you need to escape it
by adding another %
so Symfony doesn't consider it a reference to a
parameter name:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 |
# config/services.yaml
parameters:
# Parsed as 'https://symfony.com/?foo=%s&bar=%d'
url_pattern: 'https://symfony.com/?foo=%%s&bar=%%d'
|
Note
Due to the way in which parameters are resolved, you cannot use them to build paths in imports dynamically. This means that something like the following doesn't work:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 |
# config/services.yaml
imports:
- { resource: '%kernel.project_dir%/somefile.yaml' }
|
Configuration parameters are very common in Symfony applications. Some packages
even define their own parameters (e.g. when installing the translation package,
a new locale
parameter is added to the config/services.yaml
file).
See also
Later in this article you can read how to get configuration parameters in controllers and services.
Configuration Environments ¶
You have only one application, but whether you realize it or not, you need it to behave differently at different times:
- While developing, you want to log everything and expose nice debugging tools;開発中は、すべてをログに記録し、優れたデバッグ ツールを公開する必要があります。
- After deploying to production, you want that same application to be
optimized for speed and only log errors.本番環境にデプロイした後、同じアプリケーションを速度のために最適化し、エラーのみをログに記録したいと考えています。
The files stored in config/packages/
are used by Symfony to configure the
application services. In other words, you can change
the application behavior by changing which configuration files are loaded.
That's the idea of Symfony's configuration environments.
A typical Symfony application begins with three environments: dev
(for local
development), prod
(for production servers) and test
(for
automated tests). When running the application, Symfony loads
the configuration files in this order (the last files can override the values
set in the previous ones):
config/packages/*.yaml
(and*.xml
and*.php
files too);config/packages/*.yaml (および *.xml および *.php ファイルも);config/packages/<environment-name>/*.yaml
(and*.xml
and*.php
files too);config/packages//*.yaml (および *.xml および *.php ファイルも);config/services.yaml
(andservices.xml
andservices.php
files too);config/services.yaml (および services.xml と services.php ファイルも);config/services_<environment-name>.yaml
(andservices_<environment-name>.xml
andservices_<environment-name>.php
files too).config/services_.yaml (および services_.xml および services_.php ファイルも)。
Take the framework
package, installed by default, as an example:
- First,
config/packages/framework.yaml
is loaded in all environments and it configures the framework with some options;まず、config/packages/framework.yaml がすべての環境にロードされ、いくつかのオプションでフレームワークが構成されます。 - In the prod environment, nothing extra will be set as there is no
config/packages/prod/framework.yaml
file;prod 環境では、config/packages/prod/framework.yaml ファイルがないため、追加の設定はありません。 - In the dev environment, there is no file either (
config/packages/dev/framework.yaml
does not exist).開発環境では、ファイルもありません (config/packages/dev/framework.yaml は存在しません)。 - In the test environment, the
config/packages/test/framework.yaml
file is loaded to override some of the settings previously configured inconfig/packages/framework.yaml
.テスト環境では、config/packages/test/framework.yaml ファイルがロードされ、config/packages/framework.yaml で以前に構成された設定の一部が上書きされます。
In reality, each environment differs only somewhat from others. This means that
all environments share a large base of common configuration, which is put in
files directly in the config/packages/
directory.
Tip
You can also define options for different environments in a single
configuration file using the special when
keyword:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# config/packages/webpack_encore.yaml
webpack_encore:
# ...
output_path: '%kernel.project_dir%/public/build'
strict_mode: true
cache: false
# cache is enabled only in the "prod" environment
when@prod:
webpack_encore:
cache: true
# disable strict mode only in the "test" environment
when@test:
webpack_encore:
strict_mode: false
# YAML syntax allows to reuse contents using "anchors" (&some_name) and "aliases" (*some_name).
# In this example, 'test' configuration uses the exact same configuration as in 'prod'
when@prod: &webpack_prod
webpack_encore:
# ...
when@test: *webpack_prod
|
See also
See the configureContainer()
method of
the Kernel class to
learn everything about the loading order of configuration files.
Selecting the Active Environment ¶
Symfony applications come with a file called .env
located at the project
root directory. This file is used to define the value of environment variables
and it's explained in detail later in this article.
Open the .env
file (or better, the .env.local
file if you created one)
and edit the value of the APP_ENV
variable to change the environment in
which the application runs. For example, to run the application in production:
1 2 |
# .env (or .env.local)
APP_ENV=prod
|
This value is used both for the web and for the console commands. However, you
can override it for commands by setting the APP_ENV
value before running them:
1 2 3 4 5 |
# Use the environment defined in the .env file
$ php bin/console command_name
# Ignore the .env file and run this command in production
$ APP_ENV=prod php bin/console command_name
|
Creating a New Environment ¶
The default three environments provided by Symfony are enough for most projects,
but you can define your own environments too. For example, this is how you can
define a staging
environment where the client can test the project before
going to production:
- Create a configuration directory with the same name as the environment (in
this case,
config/packages/staging/
);環境と同じ名前 (この場合は config/packages/staging/) で構成ディレクトリを作成します。 - Add the needed configuration files in
config/packages/staging/
to define the behavior of the new environment. Symfony loads theconfig/packages/*.yaml
files first, so you only need to configure the differences to those files;config/packages/staging/ に必要な構成ファイルを追加して、新しい環境の動作を定義します。 symfony は config/packages/*.yaml ファイルを最初にロードするので、それらのファイルとの違いを設定するだけで済みます。 - Select the
staging
environment using theAPP_ENV
env var as explained in the previous section.前のセクションで説明したように、APP_ENV 環境変数を使用してステージング環境を選択します。
Tip
It's common for environments to be similar to each other, so you can
use symbolic links between config/packages/<environment-name>/
directories to reuse the same configuration.
Instead of creating new environments, you can use environment variables as
explained in the following section. This way you can use the same application
and environment (e.g. prod
) but change its behavior thanks to the
configuration based on environment variables (e.g. to run the application in
different scenarios: staging, quality assurance, client review, etc.)
Configuration Based on Environment Variables ¶
Using environment variables (or "env vars" for short) is a common practice to configure options that depend on where the application is run (e.g. the database credentials are usually different in production versus your local machine). If the values are sensitive, you can even encrypt them as secrets.
Use the special syntax %env(ENV_VAR_NAME)%
to reference environment variables.
The values of these options are resolved at runtime (only once per request, to
not impact performance) so you can change the application behavior without having
to clear the cache.
This example shows how you could configure the database connection using an env var:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 |
# config/packages/doctrine.yaml
doctrine:
dbal:
# by convention the env var names are always uppercase
url: '%env(resolve:DATABASE_URL)%'
# ...
|
See also
The values of env vars can only be strings, but Symfony includes some env var processors to transform their contents (e.g. to turn a string value into an integer).
To define the value of an env var, you have several options:
- Add the value to a .env file;値を .env ファイルに追加します。
- Encrypt the value as a secret;値をシークレットとして暗号化します。
- Set the value as a real environment variable in your shell or your web server.シェルまたは Web サーバーで実際の環境変数として値を設定します。
Tip
Some hosts - like SymfonyCloud - offer easy utilities to manage env vars in production.
Note
Some configuration features are not compatible with env vars. For example,
defining some container parameters conditionally based on the existence of
another configuration option. When using an env var, the configuration option
always exists, because its value will be null
when the related env var
is not defined.
Caution
Beware that dumping the contents of the $_SERVER
and $_ENV
variables
or outputting the phpinfo()
contents will display the values of the
environment variables, exposing sensitive information such as the database
credentials.
The values of the env vars are also exposed in the web interface of the Symfony profiler. In practice this shouldn't be a problem because the web profiler must never be enabled in production.
Configuring Environment Variables in .env Files ¶
Instead of defining env vars in your shell or your web server, Symfony provides
a convenient way to define them inside a .env
(with a leading dot) file
located at the root of your project.
The .env
file is read and parsed on every request and its env vars are added
to the $_ENV
& $_SERVER
PHP variables. Any existing env vars are never
overwritten by the values defined in .env
, so you can combine both.
For example, to define the DATABASE_URL
env var shown earlier in this article,
you can add:
1 2 |
# .env
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"
|
This file should be committed to your repository and (due to that fact) should only contain "default" values that are good for local development. This file should not contain production values.
In addition to your own env vars, this .env
file also contains the env vars
defined by the third-party packages installed in your application (they are
added automatically by Symfony Flex when installing packages).
Tip
Since the .env
file is read and parsed on every request, you don't need to
clear the Symfony cache or restart the PHP container if you're using Docker.
.env File Syntax ¶
Add comments by prefixing them with #
:
1 2 3 |
# database credentials
DB_USER=root
DB_PASS=pass # this is the secret password
|
Use environment variables in values by prefixing variables with $
:
1 2 |
DB_USER=root
DB_PASS=${DB_USER}pass # include the user as a password prefix
|
Caution
The order is important when some env var depends on the value of other env
vars. In the above example, DB_PASS
must be defined after DB_USER
.
Moreover, if you define multiple .env
files and put DB_PASS
first,
its value will depend on the DB_USER
value defined in other files
instead of the value defined in this file.
Define a default value in case the environment variable is not set:
1 2 |
DB_USER=
DB_PASS=${DB_USER:-root}pass # results in DB_PASS=rootpass
|
Embed commands via $()
(not supported on Windows):
1 |
START_TIME=$(date)
|
Caution
Using $()
might not work depending on your shell.
Tip
As a .env
file is a regular shell script, you can source
it in
your own shell scripts:
1 |
$ source .env
|
Overriding Environment Values via .env.local ¶
If you need to override an environment value (e.g. to a different value on your
local machine), you can do that in a .env.local
file:
1 2 |
# .env.local
DATABASE_URL="mysql://root:@127.0.0.1:3306/my_database_name"
|
This file should be ignored by git and should not be committed to your repository.
Several other .env
files are available to set environment variables in just
the right situation:
.env
: defines the default values of the env vars needed by the application;.env: アプリケーションが必要とする環境変数のデフォルト値を定義します。.env.local
: overrides the default values for all environments but only on the machine which contains the file. This file should not be committed to the repository and it's ignored in thetest
environment (because tests should produce the same results for everyone);.env.local: すべての環境のデフォルト値をオーバーライドしますが、ファイルが含まれるマシンでのみオーバーライドします。このファイルはリポジトリにコミットするべきではなく、テスト環境では無視されます (テストは全員に対して同じ結果を生成する必要があるため)。.env.<environment>
(e.g..env.test
): overrides env vars only for one environment but for all machines (these files are committed);.env。 (例: .env.test): 1 つの環境に対してのみ、すべてのマシンに対して環境変数をオーバーライドします (これらのファイルはコミットされます)。.env.<environment>.local
(e.g..env.test.local
): defines machine-specific env var overrides only for one environment. It's similar to.env.local
, but the overrides only apply to one environment..env..local (例: .env.test.local): 1 つの環境に対してのみ、マシン固有の環境変数オーバーライドを定義します。 .env.local に似ていますが、オーバーライドは 1 つの環境にのみ適用されます。
Real environment variables always win over env vars created by any of the
.env
files.
The .env
and .env.<environment>
files should be committed to the
repository because they are the same for all developers and machines. However,
the env files ending in .local
(.env.local
and .env.<environment>.local
)
should not be committed because only you will use them. In fact, the
.gitignore
file that comes with Symfony prevents them from being committed.
Configuring Environment Variables in Production ¶
In production, the .env
files are also parsed and loaded on each request. So
the easiest way to define env vars is by creating a .env.local
file on your
production server(s) with your production values.
To improve performance, you can optionally run the dump-env
command (available
in Symfony Flex 1.2 or later):
1 2 |
# parses ALL .env files and dumps their final values to .env.local.php
$ composer dump-env prod
|
After running this command, Symfony will load the .env.local.php
file to
get the environment variables and will not spend time parsing the .env
files.
Tip
Update your deployment tools/workflow to run the dump-env
command after
each deploy to improve the application performance.
Encrypting Environment Variables (Secrets) ¶
Instead of defining a real environment variable or adding it to a .env
file,
if the value of a variable is sensitive (e.g. an API key or a database password),
you can encrypt the value using the secrets management system.
Listing Environment Variables ¶
Use the debug:dotenv
command to understand how Symfony parses the different
.env
files to set the value of each environment variable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$ php bin/console debug:dotenv
Dotenv Variables & Files
========================
Scanned Files (in descending priority)
--------------------------------------
* ⨯ .env.local.php
* ⨯ .env.dev.local
* ✓ .env.dev
* ⨯ .env.local
* ✓ .env
Variables
---------
---------- ------- ---------- ------
Variable Value .env.dev .env
---------- ------- ---------- ------
FOO BAR n/a BAR
ALICE BOB BOB bob
---------- ------- ---------- ------
# look for a specific variable passing its full or partial name as an argument
$ php bin/console debug:dotenv foo
|
6.2
The option to pass variable names to debug:dotenv
was introduced in Symfony 6.2.
Additionally, and regardless of how you set environment variables, you can see all environment variables, with their values, referenced in Symfony's container configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ php bin/console debug:container --env-vars
---------------- ----------------- ---------------------------------------------
Name Default value Real value
---------------- ----------------- ---------------------------------------------
APP_SECRET n/a "471a62e2d601a8952deb186e44186cb3"
FOO "[1, "2.5", 3]" n/a
BAR null n/a
---------------- ----------------- ---------------------------------------------
# you can also filter the list of env vars by name:
$ php bin/console debug:container --env-vars foo
# run this command to show all the details for a specific env var:
$ php bin/console debug:container --env-var=FOO
|
Accessing Configuration Parameters ¶
Controllers and services can access all the configuration parameters. This includes both the parameters defined by yourself and the parameters created by packages/bundles. Run the following command to see all the parameters that exist in your application:
1 |
$ php bin/console debug:container --parameters
|
In controllers extending from the AbstractController,
use the getParameter()
helper:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// src/Controller/UserController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class UserController extends AbstractController
{
// ...
public function index(): Response
{
$projectDir = $this->getParameter('kernel.project_dir');
$adminEmail = $this->getParameter('app.admin_email');
// ...
}
}
|
In services and controllers not extending from AbstractController
, inject
the parameters as arguments of their constructors. You must inject them
explicitly because service autowiring
doesn't work for parameters:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 7 8 |
# config/services.yaml
parameters:
app.contents_dir: '...'
services:
App\Service\MessageGenerator:
arguments:
$contentsDir: '%app.contents_dir%'
|
If you inject the same parameters over and over again, use the
services._defaults.bind
option instead. The arguments defined in that option are
injected automatically whenever a service constructor or controller action
defines an argument with that exact name. For example, to inject the value of the
kernel.project_dir parameter
whenever a service/controller defines a $projectDir
argument, use this:
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 7 8 9 |
# config/services.yaml
services:
_defaults:
bind:
# pass this value to any $projectDir argument for any service
# that's created in this file (including controller arguments)
$projectDir: '%kernel.project_dir%'
# ...
|
See also
Read the article about binding arguments by name and/or type to learn more about this powerful feature.
Finally, if some service needs access to lots of parameters, instead of injecting each of them individually, you can inject all the application parameters at once by type-hinting any of its constructor arguments with the ContainerBagInterface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// src/Service/MessageGenerator.php
namespace App\Service;
// ...
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
class MessageGenerator
{
private $params;
public function __construct(ContainerBagInterface $params)
{
$this->params = $params;
}
public function someMethod()
{
// get any container parameter from $this->params, which stores all of them
$sender = $this->params->get('mailer_sender');
// ...
}
}
|
Using PHP ConfigBuilders ¶
Writing PHP config is sometimes difficult because you end up with large nested arrays and you have no autocompletion help from your favorite IDE. A way to address this is to use "ConfigBuilders". They are objects that will help you build these arrays.
Symfony generates the ConfigBuilder classes automatically in the
kernel build directory for all the
bundles installed in your application. By convention they all live in the
namespace Symfony\Config
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// config/packages/security.php
use Symfony\Config\SecurityConfig;
return static function (SecurityConfig $security) {
$security->firewall('main')
->pattern('^/*')
->lazy(true)
->anonymous();
$security
->roleHierarchy('ROLE_ADMIN', ['ROLE_USER'])
->roleHierarchy('ROLE_SUPER_ADMIN', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'])
->accessControl()
->path('^/user')
->role('ROLE_USER');
$security->accessControl(['path' => '^/admin', 'roles' => 'ROLE_ADMIN']);
};
|
Note
Only root classes in the namespace Symfony\Config
are ConfigBuilders.
Nested configs (e.g.
) are regular
PHP objects which aren't autowired when using them as an argument type.
Keep Going! ¶
Congratulations! You've tackled the basics of Symfony. Next, learn about each part of Symfony individually by following the guides. Check out:
- Formsフォーム
- Databases and the Doctrine ORMデータベースと Doctrine ORM
- Service Containerサービスコンテナ
- Security安全
- Sending Emails with Mailerメーラーでメールを送信する
- Loggingロギング
And all the other topics related to configuration:
- Environment Variable Processors環境変数プロセッサ
- Understanding how the Front Controller, Kernel and Environments Work togetherフロントコントローラー、カーネル、および環境がどのように連携するかを理解する
- Building your own Framework with the MicroKernelTraitMicroKernelTrait を使用して独自のフレームワークを構築する
- How To Create Symfony Applications with Multiple Kernels複数のカーネルを持つ symfony アプリケーションを作成する方法
- How to Override Symfony's default Directory StructureSymfony のデフォルトのディレクトリ構造をオーバーライドする方法
- How to Keep Sensitive Information Secret機密情報を秘密にする方法
- Using Parameters within a Dependency Injection Class依存性注入クラス内でのパラメーターの使用