跳到内容

配置 Symfony

编辑此页

配置文件

Symfony 应用程序通过存储在 config/ 目录中的文件进行配置,该目录具有以下默认结构

1
2
3
4
5
6
your-project/
├─ config/
│  ├─ packages/
│  ├─ bundles.php
│  ├─ routes.yaml
│  └─ services.yaml
  • routes.yaml 文件定义了 路由配置
  • services.yaml 文件配置了 服务容器 的服务;
  • bundles.php 文件启用/禁用应用程序中的扩展包;
  • config/packages/ 目录存储了应用程序中安装的每个扩展包的配置。

扩展包(在 Symfony 中也称为“bundles”,在其他项目中称为“插件/模块”)为您的项目添加了即用型功能。

当使用 Symfony Flex 时,它在 Symfony 应用程序中默认启用,扩展包会在安装期间自动更新 bundles.php 文件并在 config/packages/ 中创建新文件。例如,这是 “API Platform” 扩展包创建的默认文件

1
2
3
4
# config/packages/api_platform.yaml
api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']

将配置拆分为许多小文件对于一些 Symfony 新手来说可能显得令人生畏。但是,您会很快习惯它们,并且在安装扩展包后您很少需要更改这些文件。

提示

要了解所有可用的配置选项,请查看 Symfony 配置参考 或运行 config:dump-reference 命令。

配置格式

与其他框架不同,Symfony 不会对您配置应用程序的方式施加特定的格式,而是让您在 YAML、XML 和 PHP 之间进行选择。在整个 Symfony 文档中,所有配置示例都将以这三种格式显示。

格式之间没有任何实际区别。实际上,Symfony 会将所有格式转换为 PHP 并在运行应用程序之前缓存它们,因此甚至没有任何性能差异。

YAML 在安装扩展包时默认使用,因为它简洁且非常易读。以下是每种格式的主要优点和缺点

  • YAML:简单、清晰且可读,但并非所有 IDE 都支持它的自动完成和验证。 学习 YAML 语法
  • XML:大多数 IDE 可以自动完成/验证,并且 PHP 原生解析它,但有时它生成的配置被认为过于冗长。 学习 XML 语法
  • PHP:非常强大,它允许您使用数组或 ConfigBuilder 创建动态配置。

注意

默认情况下,Symfony 加载以 YAML 和 PHP 格式定义的配置文件。如果您以 XML 格式定义配置,请更新 configureContainer() 和/或 configureRoutes() 方法,在 src/Kernel.php 文件中添加对 .xml 文件扩展名的支持。

导入配置文件

Symfony 使用 Config 组件 加载配置文件,该组件提供了高级功能,例如导入其他配置文件,即使它们使用不同的格式

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 }

# ...

配置参数

有时,相同的配置值在多个配置文件中使用。您可以将其定义为“参数”,而不是重复它,这就像一个可重用的配置值。按照惯例,参数在 config/services.yaml 文件中的 parameters 键下定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 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

    # Enum case as parameter values
    app.some_enum: !php/enum App\Enum\PostState::Published

# ...

警告

默认情况下以及使用 XML 配置时,<parameter> 标签之间的值不会被修剪。这意味着以下参数的值将是 '\n something@example.com\n'

1
2
3
<parameter key="app.admin_email">
    something@example.com
</parameter>

如果您想修剪参数的值,请使用 trim 属性。使用它时,以下参数的值将是 something@example.com

1
2
3
<parameter key="app.admin_email" trim="true">
    something@example.com
</parameter>

定义后,您可以从任何其他配置文件中引用此参数值,使用特殊语法:将参数名称用两个 % 包裹起来(例如 %app.admin_email%

1
2
3
4
# config/packages/some_package.yaml
some_package:
    # any string surrounded by two % is replaced by that parameter value
    email_address: '%app.admin_email%'

注意

如果某些参数值包含 % 字符,您需要通过添加另一个 % 来转义它,这样 Symfony 就不会将其视为对参数名称的引用

1
2
3
4
# config/services.yaml
parameters:
    # Parsed as 'https://symfony.ac.cn/?foo=%s&amp;bar=%d'
    url_pattern: 'https://symfony.ac.cn/?foo=%%s&amp;bar=%%d'

注意

由于参数的解析方式,您不能使用它们来动态构建导入中的路径。这意味着类似以下内容不起作用:

1
2
3
# config/services.yaml
imports:
    - { resource: '%kernel.project_dir%/somefile.yaml' }

配置参数在 Symfony 应用程序中非常常见。一些扩展包甚至定义了自己的参数(例如,当安装 translation 扩展包时,一个新的 locale 参数被添加到 config/services.yaml 文件中)。

提示

按照惯例,名称以点 . 开头的参数(例如,.mailer.transport),仅在容器编译期间可用。当使用 编译器 Pass 来声明一些临时的参数时,这些参数在稍后的应用程序中将不可用。

配置参数通常是无验证的,但是您可以确保应用程序功能的重要参数不为空

1
2
/** @var ContainerBuilder $container */
$container->parameterCannotBeEmpty('app.private_key', 'Did you forget to set a value for the "app.private_key" parameter?');

如果非空参数为 null、空字符串 '' 或空数组 [],Symfony 将抛出异常。此验证不是在编译时进行的,而是在尝试检索参数值时进行的。

7.2

验证非空参数是在 Symfony 7.2 中引入的。

另请参阅

在本文的后面,您可以阅读如何在 控制器和服务中获取配置参数

配置环境

您只有一个应用程序,但是无论您是否意识到,您都需要它在不同时间表现不同

  • 开发时,您希望记录所有内容并公开漂亮的调试工具;
  • 部署到生产环境后,您希望同一个应用程序针对速度进行优化,并且只记录错误。

存储在 config/packages/ 中的文件被 Symfony 用于配置 应用程序服务。换句话说,您可以通过更改加载的配置文件来更改应用程序行为。这就是 Symfony 的 配置环境 的理念。

一个典型的 Symfony 应用程序从三个环境开始

  • dev 用于本地开发,
  • prod 用于生产服务器,
  • test 用于 自动化测试

当运行应用程序时,Symfony 按照以下顺序加载配置文件(最后的文件可以覆盖先前文件中设置的值)

  1. config/packages/*.<extension> 中的文件;
  2. config/packages/<environment-name>/*.<extension> 中的文件;
  3. config/services.<extension>;
  4. config/services_<environment-name>.<extension>.

以默认安装的 framework 扩展包为例

  • 首先,在所有环境中加载 config/packages/framework.yaml,并使用一些选项配置框架;
  • prod 环境中,由于没有 config/packages/prod/framework.yaml 文件,因此不会设置任何额外内容;
  • dev 环境中,也没有文件(config/packages/dev/framework.yaml 不存在)。
  • test 环境中,加载 config/packages/test/framework.yaml 文件以覆盖先前在 config/packages/framework.yaml 中配置的一些设置。

实际上,每个环境与其他环境只有细微的差别。这意味着所有环境共享大量的通用配置,这些配置放在直接位于 config/packages/ 目录中的文件中。

提示

您还可以在单个配置文件中使用特殊的 when 关键字为不同的环境定义选项

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

另请参阅

请参阅 内核类configureContainer() 方法,以了解有关配置文件加载顺序的所有信息。

选择活动环境

Symfony 应用程序带有一个名为 .env 的文件,位于项目根目录中。此文件用于定义环境变量的值,并在 本文的后面 详细解释。

打开 .env 文件(或者,如果您创建了 .env.local 文件,则打开该文件)并编辑 APP_ENV 变量的值以更改应用程序运行的环境。例如,要在生产环境中运行应用程序

1
2
# .env (or .env.local)
APP_ENV=prod

此值既用于 Web,也用于控制台命令。但是,您可以在运行命令之前设置 APP_ENV 值来覆盖它

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

创建一个新环境

Symfony 提供的默认三个环境对于大多数项目来说已经足够了,但是您也可以定义自己的环境。例如,以下是如何定义一个 staging 环境,客户端可以在生产环境之前测试项目

  1. 创建一个与环境名称相同的配置目录(在本例中为 config/packages/staging/);
  2. config/packages/staging/ 中添加所需的配置文件,以定义新环境的行为。Symfony 首先加载 config/packages/*.yaml 文件,因此您只需要配置与这些文件的差异;
  3. 如上一节所述,使用 APP_ENV 环境变量选择 staging 环境。

提示

环境之间通常是相似的,因此您可以在 config/packages/<environment-name>/ 目录之间使用 符号链接 来重用相同的配置。

除了创建新环境之外,您还可以使用环境变量,如下节所述。这样,您可以使用相同的应用程序和环境(例如 prod),但由于基于环境变量的配置(例如,在不同场景下运行应用程序:暂存、质量保证、客户端审查等),可以更改其行为)

基于环境变量的配置

使用 环境变量(或简称为“env vars”)是一种常见的做法,用于

  • 配置取决于应用程序运行位置的选项(例如,数据库凭据在生产环境和本地机器上通常是不同的);
  • 配置可以在生产环境中动态更改的选项(例如,更新过期的 API 密钥的值,而无需重新部署整个应用程序)。

在其他情况下,建议继续使用 配置参数

使用特殊语法 %env(ENV_VAR_NAME)% 来引用环境变量。这些选项的值在运行时解析(每个请求只解析一次,以不影响性能),因此您可以在不必清除缓存的情况下更改应用程序行为。

此示例显示了如何使用环境变量配置应用程序密钥

1
2
3
4
5
# config/packages/framework.yaml
framework:
    # by convention the env var names are always uppercase
    secret: '%env(APP_SECRET)%'
    # ...

注意

您的环境变量也可以通过 PHP 超全局变量 $_ENV$_SERVER 访问(两者是等效的)

1
2
$databaseUrl = $_ENV['DATABASE_URL']; // mysql://db_user:db_password@127.0.0.1:3306/db_name
$env = $_SERVER['APP_ENV']; // prod

但是,在 Symfony 应用程序中,没有必要使用这种方式,因为配置系统提供了一种更好的使用环境变量的方法。

另请参阅

环境变量的值只能是字符串,但是 Symfony 包含一些 环境变量处理器 来转换其内容(例如,将字符串值转换为整数)。

要定义环境变量的值,您有几种选择

如果您的应用程序尝试使用尚未定义的环境变量,您将看到一个异常。您可以通过为环境变量定义默认值来防止这种情况。为此,请使用以下语法定义一个与环境变量同名的参数

1
2
3
4
5
6
# config/packages/framework.yaml
parameters:
    # if the SECRET env var value is not defined anywhere, Symfony uses this value
    env(SECRET): 'some_secret'

# ...

提示

一些主机 - 例如 Platform.sh - 提供了简单的 实用程序来管理生产环境中的环境变量

注意

某些配置功能与环境变量不兼容。例如,基于另一个配置选项的存在有条件地定义某些容器参数。当使用环境变量时,配置选项始终存在,因为当未定义相关的环境变量时,其值将为 null

危险

请注意,转储 $_SERVER$_ENV 变量的内容或输出 phpinfo() 的内容将显示环境变量的值,从而暴露敏感信息,例如数据库凭据。

环境变量的值也暴露在 Symfony 分析器 的 Web 界面中。实际上,这不应该是一个问题,因为 Web 分析器永远不应该在生产环境中启用。

在 .env 文件中配置环境变量

Symfony 没有在您的 shell 或 Web 服务器中定义环境变量,而是提供了一种方便的方法,可以在位于项目根目录的 .env (带前导点)文件中定义它们。

.env 文件在每个请求上读取和解析,其环境变量被添加到 $_ENV & $_SERVER PHP 变量中。任何现有的环境变量都永远不会.env 中定义的值覆盖,因此您可以将两者结合使用。

例如,要定义本文前面显示的 DATABASE_URL 环境变量,您可以添加

1
2
# .env
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"

此文件应提交到您的存储库,并且(由于这个事实)应该只包含对本地开发有用的“默认”值。此文件不应包含生产值。

除了您自己的环境变量之外,此 .env 文件还包含应用程序中安装的第三方扩展包定义的环境变量(它们由 Symfony Flex 在安装扩展包时自动添加)。

提示

由于 .env 文件在每个请求上都会被读取和解析,因此如果您正在使用 Docker,则无需清除 Symfony 缓存或重启 PHP 容器。

.env 文件语法

通过在注释前加上 # 来添加注释

1
2
3
# database credentials
DB_USER=root
DB_PASS=pass # this is the secret password

通过在值中的变量前加上 $ 来使用环境变量

1
2
DB_USER=root
DB_PASS=${DB_USER}pass # include the user as a password prefix

警告

当某些环境变量依赖于其他环境变量的值时,顺序很重要。在上面的示例中,DB_PASS 必须在 DB_USER 之后定义。此外,如果您定义了多个 .env 文件并将 DB_PASS 放在首位,则其值将取决于其他文件中定义的 DB_USER 值,而不是此文件中定义的值。

在环境变量未设置的情况下定义默认值

1
2
DB_USER=
DB_PASS=${DB_USER:-root}pass # results in DB_PASS=rootpass

通过 $() 嵌入命令(Windows 上不支持)

1
START_TIME=$(date)

警告

使用 $() 可能无法工作,具体取决于您的 shell。

提示

由于 .env 文件是一个常规的 shell 脚本,您可以在自己的 shell 脚本中 source

1
$ source .env

通过 .env.local 覆盖环境值

如果您需要覆盖环境值(例如,在本地机器上使用不同的值),您可以在 .env.local 文件中执行此操作

1
2
# .env.local
DATABASE_URL="mysql://root:@127.0.0.1:3306/my_database_name"

此文件应被 git 忽略,并且不应提交到您的存储库。还有其他几个 .env 文件可用于在恰好正确的情况下设置环境变量

  • .env:定义应用程序所需的环境变量的默认值;
  • .env.local:覆盖所有环境的默认值,但仅在包含该文件的机器上。此文件不应提交到存储库,并且在 test 环境中被忽略(因为测试应为每个人产生相同的结果);
  • .env.<environment>(例如 .env.test):仅覆盖一个环境的环境变量,但适用于所有机器(这些文件提交);
  • .env.<environment>.local (例如 .env.test.local): 定义特定于机器的环境变量覆盖,仅适用于一个环境。它类似于 .env.local,但覆盖仅适用于一个环境。

真实 环境变量始终优先于任何 .env 文件创建的环境变量。请注意,此行为取决于 variables_order 配置,该配置必须包含 E 以公开 $_ENV 超全局变量。这是 PHP 中的默认配置。

.env.env.<environment> 文件应提交到代码仓库,因为它们对于所有开发人员和机器都是相同的。但是,以 .local 结尾的 env 文件(.env.local.env.<environment>.local不应提交,因为只有您会使用它们。实际上,Symfony 自带的 .gitignore 文件会阻止它们被提交。

覆盖系统定义的环境变量

如果您需要覆盖系统定义的环境变量,请使用 loadEnv()bootEnv()populate() 方法定义的 overrideExistingVars 参数

1
2
3
4
5
6
use Symfony\Component\Dotenv\Dotenv;

$dotenv = new Dotenv();
$dotenv->loadEnv(__DIR__.'/.env', overrideExistingVars: true);

// ...

这将覆盖系统定义的环境变量,但不会覆盖 .env 文件中定义的环境变量。

在生产环境中配置环境变量

在生产环境中,.env 文件也会在每次请求时被解析和加载。因此,定义环境变量的最简单方法是在您的生产服务器上创建一个包含生产值的 .env.local 文件。

为了提高性能,您可以选择运行 dump-env Composer 命令

1
2
# parses ALL .env files and dumps their final values to .env.local.php
$ composer dump-env prod

如果您的生产环境中没有安装 Composer,您可以使用 dotenv:dump 命令代替(在 Symfony Flex 1.2 或更高版本中可用)。该命令默认未注册,因此您必须首先在您的服务中注册

1
2
3
# config/services.yaml
services:
    Symfony\Component\Dotenv\Command\DotenvDumpCommand: ~

然后,运行该命令

1
2
# parses ALL .env files and dumps their final values to .env.local.php
$ APP_ENV=prod APP_DEBUG=0 php bin/console dotenv:dump

运行此命令后,Symfony 将加载 .env.local.php 文件以获取环境变量,并且不会花费时间解析 .env 文件。

提示

更新您的部署工具/工作流程,以便在每次部署后运行 dotenv:dump 命令,以提高应用程序性能。

将环境变量存储在其他文件中

默认情况下,环境变量存储在项目根目录下的 .env 文件中。但是,您可以通过多种方式将它们存储在其他文件中。

如果您使用 Runtime 组件,则 dotenv 路径是您可以在 composer.json 文件中设置的选项的一部分

1
2
3
4
5
6
7
8
9
{
    // ...
    "extra": {
        // ...
        "runtime": {
            "dotenv_path": "my/custom/path/to/.env"
        }
    }
}

作为替代选项,您可以直接在您的 bootstrap.php 文件或应用程序的任何其他文件中调用 Dotenv

1
2
3
use Symfony\Component\Dotenv\Dotenv;

(new Dotenv())->bootEnv(dirname(__DIR__).'my/custom/path/to/.env');

然后,Symfony 将在该文件中查找环境变量,也会在本地和特定于环境的文件中查找(例如 .*.local.*.<environment>.local)。阅读 如何覆盖环境变量 以了解更多信息。

如果您需要知道 Symfony 正在使用的 .env 文件的路径,您可以在您的应用程序中读取 SYMFONY_DOTENV_PATH 环境变量。

7.1

SYMFONY_DOTENV_PATH 环境变量在 Symfony 7.1 中引入。

加密环境变量 (密钥)

如果变量的值是敏感的(例如 API 密钥或数据库密码),您可以加密该值,而不是定义真实的环境变量或将其添加到 .env 文件中,您可以使用 secrets 管理系统

列出环境变量

使用 debug:dotenv 命令来了解 Symfony 如何解析不同的 .env 文件来设置每个环境变量的值

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

此外,无论您如何设置环境变量,您都可以查看 Symfony 容器配置中引用的所有环境变量及其值,您还可以查看每个环境变量在容器中出现的次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ php bin/console debug:container --env-vars

------------ ----------------- ------------------------------------ -------------
 Name         Default value     Real value                           Usage count
------------ ----------------- ------------------------------------ -------------
 APP_SECRET   n/a               "471a62e2d601a8952deb186e44186cb3"   2
 BAR          n/a               n/a                                  1
 BAZ          n/a               "value"                              0
 FOO          "[1, "2.5", 3]"   n/a                                  1
------------ ----------------- ------------------------------------ -------------

# 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

创建您自己的逻辑来加载 Env Vars

如果默认的 Symfony 行为不符合您的需求,您可以实现自己的逻辑来加载环境变量。为此,创建一个服务,该服务的类实现 EnvVarLoaderInterface

注意

如果您正在使用 默认的 services.yaml 配置,自动配置功能将自动启用并标记此服务。否则,您需要注册并使用 container.env_var_loader 标记 标记您的服务

假设您有一个名为 env.json 的 JSON 文件,其中包含您的环境变量

1
2
3
4
5
6
{
    "vars": {
        "APP_ENV": "prod",
        "APP_DEBUG": false
    }
}

您可以定义一个如下所示的类 JsonEnvVarLoader 以从文件中填充环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace App\DependencyInjection;

use Symfony\Component\DependencyInjection\EnvVarLoaderInterface;

final class JsonEnvVarLoader implements EnvVarLoaderInterface
{
    private const ENV_VARS_FILE = 'env.json';

    public function loadEnvVars(): array
    {
        $fileName = __DIR__.\DIRECTORY_SEPARATOR.self::ENV_VARS_FILE;
        if (!is_file($fileName)) {
            // throw an exception or just ignore this loader, depending on your needs
        }

        $content = json_decode(file_get_contents($fileName), true);

        return $content['vars'];
    }
}

就是这样!现在应用程序将在当前目录中查找 env.json 文件以填充环境变量(除了已经存在的 .env 文件之外)。

提示

如果您希望一个环境变量在某个环境中具有值,但在另一个环境中回退到加载器,请为您要使用加载器的环境将该环境变量分配一个空值

1
2
3
4
5
# .env (or .env.local)
APP_ENV=prod

# .env.prod (or .env.prod.local) - this will fallback on the loaders you defined
APP_ENV=

访问配置参数

控制器和服务可以访问所有配置参数。这包括 您自己定义的参数 和包/bundle 创建的参数。运行以下命令以查看应用程序中存在的所有参数

1
$ php bin/console debug:container --parameters

在从 AbstractController 扩展的控制器中,使用 getParameter() 助手

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');

        // ...
    }
}

在不从 AbstractController 扩展的服务和控制器中,将参数作为其构造函数的参数注入。您必须显式注入它们,因为 服务自动装配 不适用于参数

1
2
3
4
5
6
7
8
# config/services.yaml
parameters:
    app.contents_dir: '...'

services:
    App\Service\MessageGenerator:
        arguments:
            $contentsDir: '%app.contents_dir%'

如果您一遍又一遍地注入相同的参数,请改用 services._defaults.bind 选项。每当服务构造函数或控制器操作定义具有该确切名称的参数时,都会自动注入该选项中定义的参数。例如,要注入 kernel.project_dir 参数 的值,只要服务/控制器定义了 $projectDir 参数,请使用以下方法

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%'

    # ...

另请参阅

阅读关于 按名称和/或类型绑定参数 的文章,以了解有关此强大功能的更多信息。

最后,如果某些服务需要访问大量参数,您可以一次性注入所有应用程序参数,而不是单独注入每个参数,方法是使用 ContainerBagInterface 类型提示其任何构造函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/Service/MessageGenerator.php
namespace App\Service;

// ...

use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;

class MessageGenerator
{
    public function __construct(
        private ContainerBagInterface $params,
    ) {
    }

    public function someMethod(): void
    {
        // get any container parameter from $this->params, which stores all of them
        $sender = $this->params->get('mailer_sender');
        // ...
    }
}

使用 PHP ConfigBuilders

编写 PHP 配置有时很困难,因为您最终会得到大型嵌套数组,并且您无法从您最喜欢的 IDE 获得自动完成帮助。解决这个问题的一种方法是使用“ConfigBuilders”。它们是帮助您构建这些数组的对象。

Symfony 会在 kernel build directory 中为您的应用程序中安装的所有 bundle 自动生成 ConfigBuilder 类。按照惯例,它们都位于命名空间 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): void {
    $security->firewall('main')
        ->pattern('^/*')
        ->lazy(true)
        ->security(false);

    $security
        ->roleHierarchy('ROLE_ADMIN', ['ROLE_USER'])
        ->roleHierarchy('ROLE_SUPER_ADMIN', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'])
        ->accessControl()
            ->path('^/user')
            ->roles('ROLE_USER');

    $security->accessControl(['path' => '^/admin', 'roles' => 'ROLE_ADMIN']);
};

注意

只有命名空间 Symfony\Config 中的根类才是 ConfigBuilders。嵌套配置(例如 \Symfony\Config\Framework\CacheConfig)是常规 PHP 对象,当将它们用作参数类型时不会自动装配。

注意

为了在您的 IDE/编辑器中获得 ConfigBuilders 自动完成功能,请确保不排除生成这些类的目录(默认情况下,在 var/cache/dev/Symfony/Config/ 中)。

本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本