跳到內容

設定 Symfony

編輯此頁面

設定檔

Symfony 應用程式透過儲存在 config/ 目錄中的檔案進行設定,該目錄具有以下預設結構

1
2
3
4
5
6
your-project/
├─ config/
│  ├─ packages/
│  ├─ bundles.php
│  ├─ routes.yaml
│  └─ services.yaml
  • The routes.yaml 檔案定義了 路由設定
  • The services.yaml 檔案設定了 服務容器 的服務;
  • The bundles.php 檔案啟用/停用應用程式中的套件;
  • The config/packages/ 目錄儲存了應用程式中每個已安裝套件的設定。

套件(在 Symfony 中也稱為「bundles」,在其他專案中稱為「plugins/modules」)為您的專案新增了現成的功能。

當使用 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 格式定義設定,請更新 src/Kernel.php 檔案中的 configureContainer() 和/或 configureRoutes() 方法,以新增對 .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.dev.org.tw/?foo=%s&amp;bar=%d'
    url_pattern: 'https://symfony.dev.org.tw/?foo=%%s&amp;bar=%%d'

注意

由於參數解析的方式,您無法使用它們在匯入中動態建立路徑。這表示像以下這樣的操作是無效的:

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

設定參數在 Symfony 應用程式中非常常見。有些套件甚至定義了自己的參數(例如,安裝翻譯套件時,會在 config/services.yaml 檔案中新增一個新的 locale 參數)。

提示

依照慣例,名稱以點 . 開頭的參數(例如,.mailer.transport)僅在容器編譯期間可用。當使用 Compiler Passes 宣告一些稍後在應用程式中不可用的暫時參數時,它們非常有用。

設定參數通常是免驗證的,但是您可以確保應用程式功能的基本參數不是空的

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

另請參閱

請參閱 Kernel 類別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),但可以透過基於環境變數的設定來變更其行為(例如,在不同的情境中執行應用程式:staging、品質保證、客戶審查等)

基於環境變數的設定

使用 環境變數(或簡稱「環境變數」)是一種常見的做法,用於

  • 設定取決於應用程式執行位置的選項(例如,資料庫認證在生產環境與本機電腦上通常不同);
  • 設定可以在生產環境中動態變更的選項(例如,更新過期的 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 提供了一種方便的方式,可以在位於專案根目錄的 .env 檔案(帶有前導點)內定義環境變數,而不是在 Shell 或 Web 伺服器中定義環境變數。

每次請求都會讀取和解析 .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.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 component,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 中引入的。

加密環境變數(密鑰)

除了定義真正的環境變數或將其添加到 .env 檔案之外,如果變數的值是敏感的(例如 API 金鑰或資料庫密碼),您可以使用 secrets management system 加密該值。

列出環境變數

使用 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

建立您自己的邏輯來載入環境變數

如果預設的 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() 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');

        // ...
    }
}

在未從 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 選項。每當服務建構子或控制器動作定義具有該確切名稱的引數時,都會自動注入該選項中定義的引數。例如,每當服務/控制器定義 $projectDir 引數時,要注入 kernel.project_dir 參數 的值,請使用這個。

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 授權條款授權。
目錄
    版本