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

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
PHP與Python:了解差異PHP與Python:了解差異Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

php:死亡還是簡單地適應?php:死亡還是簡單地適應?Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來:改編和創新PHP的未來:改編和創新Apr 11, 2025 am 12:01 AM

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

您什麼時候使用特質與PHP中的抽像類或接口?您什麼時候使用特質與PHP中的抽像類或接口?Apr 10, 2025 am 09:39 AM

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

什麼是依賴性注入容器(DIC),為什麼在PHP中使用一個?什麼是依賴性注入容器(DIC),為什麼在PHP中使用一個?Apr 10, 2025 am 09:38 AM

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

與常規PHP陣列相比,解釋SPL SplfixedArray及其性能特徵。與常規PHP陣列相比,解釋SPL SplfixedArray及其性能特徵。Apr 10, 2025 am 09:37 AM

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP如何安全地上載文件?PHP如何安全地上載文件?Apr 10, 2025 am 09:37 AM

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

什麼是無效的合併操作員(??)和無效分配運算符(?? =)?什麼是無效的合併操作員(??)和無效分配運算符(?? =)?Apr 10, 2025 am 09:33 AM

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。