Drupal 8模塊 - 配置管理和服務容器
核心要點
- 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中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

RESTAPI設計原則包括資源定義、URI設計、HTTP方法使用、狀態碼使用、版本控制和HATEOAS。 1.資源應使用名詞表示並保持層次結構。 2.HTTP方法應符合其語義,如GET用於獲取資源。 3.狀態碼應正確使用,如404表示資源不存在。 4.版本控制可通過URI或頭部實現。 5.HATEOAS通過響應中的鏈接引導客戶端操作。

匿名類在PHP中的主要作用是創建一次性使用的對象。 1.匿名類允許在代碼中直接定義沒有名字的類,適用於臨時需求。 2.它們可以繼承類或實現接口,增加靈活性。 3.使用時需注意性能和代碼可讀性,避免重複定義相同的匿名類。

在PHP中,異常處理通過try,catch,finally,和throw關鍵字實現。 1)try塊包圍可能拋出異常的代碼;2)catch塊處理異常;3)finally塊確保代碼始終執行;4)throw用於手動拋出異常。這些機制幫助提升代碼的健壯性和可維護性。

PHP中有四種主要錯誤類型:1.Notice:最輕微,不會中斷程序,如訪問未定義變量;2.Warning:比Notice嚴重,不會終止程序,如包含不存在文件;3.FatalError:最嚴重,會終止程序,如調用不存在函數;4.ParseError:語法錯誤,會阻止程序執行,如忘記添加結束標籤。

在PHP中,include,require,include_once,require_once的區別在於:1)include產生警告並繼續執行,2)require產生致命錯誤並停止執行,3)include_once和require_once防止重複包含。這些函數的選擇取決於文件的重要性和是否需要防止重複包含,合理使用可以提高代碼的可讀性和可維護性。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。
