首頁 > 後端開發 > php教程 > Drupal 8模塊 - 配置管理和服務容器

Drupal 8模塊 - 配置管理和服務容器

Christopher Nolan
發布: 2025-02-21 10:17:09
原創
1013 人瀏覽過

Drupal 8 Modules - Configuration Management and the Service Container

核心要點

  • Drupal 8 的 ConfigFormBase 類提供了額外的功能來與配置系統交互,允許將表單轉換為存儲值的工具。這可以通過用 ConfigFormBase 替換擴展類並在表單中進行必要的更改來實現。 Drupal 8 中的配置存儲在 YAML 文件中,可以通過 UI 進行更改,以便跨不同站點部署。
  • Drupal 8 中的服務容器允許創建服務,即執行全局操作的 PHP 類,並將其註冊到服務容器中以供訪問。依賴注入用於將對像傳遞給其他對象,確保解耦。可以通過在模塊的根目錄中創建 demo.services.yml 文件來註冊服務。
  • Drupal 8 中的依賴注入是一種設計模式,允許一個對象提供另一個對象的依賴項,使代碼更模塊化且更易於測試。這可以通過擴展 ControllerBase 類或實現 ContainerInjectionInterface 來實現。還可以使用 Drupal 類全局訪問服務。

請注意,由於撰寫本文時 Drupal 8 正在進行開發過程,因此某些代碼部分可能已過時。請查看此存儲庫,我嘗試更新示例代碼並使其與最新的 Drupal 8 版本兼容。

在之前的關於 Drupal 8 模塊開發的文章中,我們研究了創建塊類型和表單。我們已經看到塊現在是可重用的,以及定義塊類型所需的一切都在一個類中完成。類似地,表單生成函數也分組在一個類中,其中特定方法執行的任務類似於我們在 Drupal 7 中習慣的任務。

在本教程中,我將從我們上次結束的地方繼續。我將說明如何將我們的 DemoForm 轉換為用於通過 Drupal 8 配置系統存儲值的表單。之後,我們將通過示例說明服務容器和依賴注入。

別忘了,如果您想獲取本教程系列中編寫的全部代碼,可以查看此存儲庫。

配置表單

當我們第一次定義 DemoForm 時,我們擴展了 FormBase 類,這是 FormInterface 的最簡單實現。但是,Drupal 8 還附帶了一個 ConfigFormBase,它提供了一些附加功能,使與配置系統交互變得非常容易。

我們現在要做的是將 DemoForm 轉換為一個用於存儲用戶輸入的電子郵件地址的表單。我們應該做的第一件事是用 ConfigFormBase 替換擴展類(當然還要 use 它):

use Drupal\Core\Form\ConfigFormBase;

class DemoForm extends ConfigFormBase {
登入後複製
登入後複製
登入後複製

在我們繼續更改表單中的其他內容之前,讓我們了解一下 Drupal 8 中的簡單配置是如何工作的。我說“簡單”,因為還有更複雜的配置實體,我們今天不會介紹。就目前而言,模塊(核心或 contrib)提供的配置存儲在 YAML 文件中。啟用模塊後,此數據將導入到數據庫中(以便在使用時提高性能)。通過 UI,我們可以更改此配置,然後可以輕鬆地將其導出到 YAML 文件中,以便跨不同站點部署。

模塊可以在模塊根目錄的 config/install 文件夾中提供一個 YAML 文件中的默認配置。此文件的命名約定是在其前面加上模塊的名稱。因此,讓我們創建一個名為 demo.settings.yml 的文件。在這個文件中,讓我們粘貼以下內容:

demo:
  email_address: demo@demo.com
登入後複製
登入後複製

這是一個嵌套結構(就像 PHP 中的關聯數組)。在 demo 鍵下,我們有另一個鍵值對。通常,要訪問這些嵌套值,我們使用點 (.)。在我們的例子中是 demo.email_address

一旦我們有了這個文件,你需要記住的一件重要事情是,只有在安裝模塊時才會導入此文件。因此,繼續重新安裝它。現在我們可以回到我們的表單並逐一查看需要調整的方法。

這就是 buildForm() 方法現在的樣子:

public function buildForm(array $form, array &$form_state) {

  $form = parent::buildForm($form, $form_state);

  $config = $this->config('demo.settings');

  $form['email'] = array(
    '#type' => 'email',
    '#title' => $this->t('Your .com email address.'),
    '#default_value' => $config->get('demo.email_address')
  );

  return $form;
}
登入後複製
登入後複製

首先,與 FormBase 相反,ConfigFormBase 類也實現了此方法,以便向表單數組(提交按鈕)添加元素。因此,在添加我們自己的元素之前,我們可以使用父類之前所做的操作。

現在對於配置部分。 Drupal 8 提供了一個 Config 對象,我們可以用它來與配置交互。某些類已經通過依賴注入獲得了它。 ConfigFormBase 就是這樣一個類。

如您所見,我們正在使用父類的 config() 方法來檢索一個 Config 對象,該對像已填充我們的 demo.settings 簡單配置。然後,對於電子郵件表單元素的 #default_value,我們使用 Config 對象的 get() 方法來檢索電子郵件地址的值。

接下來,我們只需要更改提交處理程序,因為 validateForm() 方法現在可以保持不變:

public function submitForm(array &$form, array &$form_state) {

  $config = $this->config('demo.settings');
  $config->set('demo.email_address', $form_state['values']['email']);
  $config->save();

  return parent::submitForm($form, $form_state);
}
登入後複製

在此方法中,我們首先檢索我們配置的 Config 對象(就像我們之前做的那樣)。然後,我們使用它的 set() 方法將 email_address 的值更改為用戶提交的值。然後我們使用 save() 方法保存配置。最後,我們擴展了父提交處理程序,因為它確實包含一些功能(在這種情況下,它會將 Drupal 消息設置為屏幕)。

就是這樣。您可以清除緩存並試一試。通過提交一個新的電子郵件地址,您將其存儲在配置中。 demo.settings.yml 文件當然不會更改,但是您可以去導出 demo.settings 配置並將其導入到另一個站點。

服務容器和依賴注入

接下來我們要看的是服務容器。服務背後的理念是將功能分解成可重用的組件。因此,服務是一個執行某些全局操作並註冊到服務容器以便訪問的 PHP 類。

依賴注入是我們傳遞對像以確保解耦的方式。每個服務都需要處理一件事情,如果它需要另一個服務,則後者可以注入到前者中。但我們馬上就會看到如何操作。

接下來,我們將創建一個非常簡單的服務並將其註冊到容器中。它只有一個真正的返回簡單值的方法。然後,我們將該服務作為依賴項注入到我們的 DemoController 中並使用服務提供的值。

為了註冊服務,我們需要創建一個位於模塊根目錄的 demo.services.yml 文件,其內容如下:

use Drupal\Core\Form\ConfigFormBase;

class DemoForm extends ConfigFormBase {
登入後複製
登入後複製
登入後複製

文件命名約定是 module_name.services.yml

第一行創建了一個服務數組。第二行定義了第一個服務(稱為 demo_service,以模塊名稱為前綴)。第三行指定將為此服務實例化的類。接下來是在我們模塊的 src/ 文件夾中創建 DemoService.php 類文件。這就是我的服務所做的(實際上什麼也沒有,只是為了說明如何使用它):

demo:
  email_address: demo@demo.com
登入後複製
登入後複製

這裡不需要解釋任何內容,因為它非常基礎。接下來,讓我們轉向我們的 DemoController 並使用此服務。我們可以通過兩種方式做到這一點:通過 Drupal 類全局訪問容器或使用依賴注入將此類的對像傳遞給我們的控制器。最佳實踐建議我們應該採用第二種方式,所以這就是我們將要做的。但有時您需要全局訪問服務。為此,您可以執行以下操作:

public function buildForm(array $form, array &$form_state) {

  $form = parent::buildForm($form, $form_state);

  $config = $this->config('demo.settings');

  $form['email'] = array(
    '#type' => 'email',
    '#title' => $this->t('Your .com email address.'),
    '#default_value' => $config->get('demo.email_address')
  );

  return $form;
}
登入後複製
登入後複製

現在 $service 是我們剛剛創建的 DemoService 類的對象。但是讓我們看看如何在 DemoController 類中將我們的服務作為依賴項注入。我將首先解釋需要做什麼,然後您將看到包含所有對其進行的更改的完整控制器。

首先,我們需要訪問服務容器。對於控制器來說,這非常容易。我們可以擴展 ControllerBase 類,這除了其他一些幫助程序之外還給我們提供了這一點。或者,我們的控制器可以實現 ContainerInjectionInterface,這也可以讓我們訪問容器。但是我們將堅持使用 ControllerBase,因此我們需要 use 該類。

接下來,我們需要 use Symfony 2 ContainerInterface 作為 create() 方法的要求,該方法實例化控制器的另一個對象並將我們想要的服務傳遞給它。

最後,我們將需要一個構造函數來獲取傳遞的服務對象(create() 返回的對象)並將它們分配給屬性以供以後使用。 create() 方法返回對象的順序需要反映它們傳遞給構造函數的順序。

因此,讓我們看看我們修改後的 DemoController

use Drupal\Core\Form\ConfigFormBase;

class DemoForm extends ConfigFormBase {
登入後複製
登入後複製
登入後複製

如您所見,所有步驟都在這裡。 create() 方法創建了我們控制器類的新實例,並將從容器檢索的服務傳遞給它。最後,DemoService 類的實例存儲在 $demoService 屬性中,我們可以使用它來調用其 getDemoValue() 方法。然後,此值將用於“Hello”消息中。清除緩存並試一試。轉到 demo/ 路徑,您應該看到頁面上打印的“Hello Upchuk!”。

我相信您可以看到服務容器的強大功能,因為我們現在可以編寫解耦的功能並將其傳遞到需要的地方。我沒有向您展示如何操作,但是您也可以在註冊服務時聲明依賴項。這意味著當 Drupal 實例化服務對象時,它也將為其所有依賴項這樣做,並將它們傳遞給其構造函數。您可以在此文檔頁面上閱讀有關如何執行此操作的更多信息。

結論

在本文中,我們研究了很多很酷的東西。我們已經看到了配置系統如何管理簡單的配置以及為此提供的哪些“表單”功能。我鼓勵您探索 ConfigFormBase 的實現方式以及擴展它時可用的功能。此外,您應該在 UI 中使用在站點之間導入/導出配置進行練習。從現在開始,這將是對部署過程的一大改進。

然後,我們研究了服務、它們是什麼以及它們如何工作。一種維護可重用且解耦的功能塊的好方法,這些功能塊可從任何地方訪問。我希望依賴注入的概念不再那麼可怕(如果它對您來說是的話)。它基本上等同於將參數傳遞給過程函數,但由 Symfony 及其強大的服務容器在幕後使用構造函數方法(或 setter)完成。

關於構建 Drupal 8 模塊的常見問題:配置管理和服務容器

服務容器在 Drupal 8 中的作用是什麼?

Drupal 8 中的服務容器是一個關鍵組件,用於管理服務的創建,服務是在 Drupal 應用程序中全局使用的對象。它確保每個服務只實例化一次,從而節省內存並提高性能。服務容器還處理依賴注入,這是一種設計模式,允許一個對象提供另一個對象的依賴項。這使代碼更模塊化、更易於測試並促進更好的組織。

如何在 Drupal 8 中定義新服務?

要在 Drupal 8 中定義新服務,您需要在模塊的根目錄中創建一個 services.yml 文件。此文件應包含服務的名稱、類和參數。該類應是實現服務的類的完全限定名稱,參數應為服務所依賴的任何服務或參數。

Drupal 8 中的配置管理的目的是什麼?

Drupal 8 中的配置管理是一個系統,允許您以一致的方式管理站點配置數據。它使您可以導入、導出和同步配置數據,這在將配置更改從開發環境移動到生產站點時非常有用。它還提供了一種跟踪和管理站點配置隨時間推移的變化的方法。

如何使用配置管理系統導出和導入配置數據?

要在 Drupal 8 中導出配置數據,您可以使用管理面板中的配置管理界面或使用 Drush 命令。導出的數據將採用 YAML 格式,可以輕鬆讀取和編輯。要導入配置數據,您可以通過配置管理界面上傳導出的 YAML 文件或使用 Drush 命令。請記住,在導入配置數據之前備份您的站點,以防止任何潛在的數據丟失。

什麼是依賴注入,為什麼它在 Drupal 8 中很重要?

依賴注入是一種設計模式,允許一個對象提供另一個對象的依賴項。在 Drupal 8 中,它用於使服務和控制器更模塊化且更易於測試。不是在對象內部創建依賴項,而是通過構造函數或 setter 方法傳遞(注入)它們。這使代碼更易於測試、更靈活且耦合度更低。

如何在我的 Drupal 8 服務中註入依賴項?

要在 Drupal 8 中的服務中註入依賴項,您需要在 services.yml 文件中服務的定義中定義它們。依賴項應列在 arguments 鍵下。創建服務時,服務容器將自動將這些依賴項傳遞給服務的構造函數。

Drupal 8 中的服務和插件有什麼區別?

在 Drupal 8 中,服務是一個執行應用程序中全局任務的對象,而插件是一個以可插入方式執行特定任務的對象。服務在 services.yml 文件中定義,並由服務容器管理,而插件由插件管理器發現和實例化。

如何在 Drupal 8 中覆蓋服務?

要在 Drupal 8 中覆蓋服務,您需要在模塊的 services.yml 文件中定義一個與要覆蓋的服務同名的服務。您的新服務應擴展原始服務的類並覆蓋要更改的方法。

如何使用配置管理系統跟踪站點配置的更改?

Drupal 8 中的配置管理系統提供了一種通過配置快照系統跟踪站點配置更改的方法。每當您導入或同步配置數據時,此系統都會對站點的活動配置進行快照。然後,您可以比較這些快照以查看進行了哪些更改。

services.yml 文件在 Drupal 8 中的作用是什麼?

Drupal 8 中的 services.yml 文件是定義模塊服務的場所。每個服務都使用唯一的名稱、實現服務的類的完全限定名稱以及服務所依賴的任何服務或參數來定義。 services.yml 文件由服務容器讀取,服務容器管理服務的創建和注入。

以上是Drupal 8模塊 - 配置管理和服務容器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板