了解成功的 Drupal 站點更新的更新和更新後掛鉤
已發表: 2023-04-25在核心更新或模塊更新期間,確保您的 Drupal 網站的穩定性和完整性至關重要。 幸運的是,Update API 模塊和 Update/Post Update Hooks 可以提供幫助。
Update API 模塊提供更新 Drupal 站點上的代碼和模塊所必需的掛鉤。 這些掛鉤只不過是更新和更新後掛鉤,它們允許開發人員根據他們的需要自定義更新。
在本文中,我們將討論更新 API、什麼是更新和更新後掛鉤以及何時以及如何使用它們。 通過了解這兩種類型的掛鉤,您可以毫不費力地成功更新您的 Drupal 站點。 讓我們開始吧!

更新 API
在現有站點上工作時,當您更新模塊中的代碼時,您可能需要更新存儲的數據,以便存儲的數據與新代碼兼容。 您可能已經註意到諸如“網站遇到意外錯誤”之類的錯誤在您面前閃過。 可怕吧!? 我知道! 這就是 Drupal 的更新 API 來拯救我們的地方。
如果更新是在同一主要版本的 Drupal 核心中的模塊的兩個次要版本之間進行的,則可以使用更新 API 來更新數據。 更新 API 允許您提供代碼,以便在您的模塊對其數據模型進行更改時對存儲的數據執行更新。 數據模型更改是指任何使現有站點上存儲的數據與該站點更新後的代碼庫不兼容的更改。 這些數據模型更改涉及:
更新配置架構
- 添加/刪除/重命名配置鍵。
- 更改配置鍵的數據類型。
- 更改配置鍵的預期默認值等。
更新數據庫架構
- 添加/更改/刪除數據庫表或字段。
- 將存儲的數據移動到不同的字段或表。
- 更改存儲數據的格式等
更新實體和字段
- 向現有實體類型添加新的基本字段。
- 將字段從過時類型更新為新類型等。
更新數據
- 操作現有站點上的存儲數據。
使用更新掛鉤
Hook hook_update_N() 用於在模塊的次要版本之間引入更新。 這些掛鉤位於您的模塊中的*.install文件中。
hook_update_N() 的寫法是(模塊名)_update_(編號)。 這裡N包括:
- 1 位或 2 位數字表示 Drupal 核心兼容性(Drupal 8、9、10 等)
- 接下來的 1 位是您模塊的主要發布版本
- 順序計數的最後2位,從01開始
例子:
example_update_9201(): 9.x-2.x 版本的第一次更新。
其中“example”是模塊的名稱,第一個數字表示 Drupal 核心版本“9”,數字“2”表示模塊的主要發布版本,最後兩位數字“01”表示為編寫的第一個更新函數模塊“示例”。
掛鉤實現函數的數字部分(即上例中的 9201)存儲在數據庫中,以跟踪哪些更新已被執行。 所以你不應該重新編號更新函數。
要了解模塊“存儲在數據庫中的示例”的當前模式版本,請使用:
drush php-eval "echo drupal_get_installed_schema_version('example');"

要手動將模塊“example”的當前架構版本設置回“9201”,請使用:
drush php-eval "echo drupal_set_installed_schema_version('example', '9201');"

注意:請盡量避免在生產站點上使用 drupal_set_installed_schema_version() 函數,因為它會直接更新您的數據庫。 您可以在開發期間在本地或較低的測試環境中使用它來重置架構版本。
在 update hook 函數之前的文檔塊註釋中添加適當的描述,因為它將在運行時為用戶打印。
Structure of hook_update_N(): /** * A aimple hook_update_N() hook. */ function example_update_9201() { // Code goes here. }
這些鉤子按排序順序執行,即 example_update_9201() 鉤子在 example_update_9202() 之前執行,接下來是 9203、9204 等等。
您還可以通過引入掛鉤之間的依賴關係來更改這些掛鉤的排序順序。 使用掛鉤 hook_update_dependencies() 在兩個更新掛鉤之間運行更新。

所有更新掛鉤都是批量執行的,它們還支持項目的批量處理。 所有更新掛鉤都可以訪問 $sandbox 參數,該參數可用於在更新掛鉤中創建批處理,以便一次處理大量數據而不會導致任何 PHP 超時。
添加新配置密鑰的更新掛鉤的簡單示例:
目前,example_module.settings.yml 文件包含:



要向配置添加新的密鑰“描述”:
- 將“描述”鍵添加到設置文件

- 在 example_module.install 文件中添加 update_hook:

- 使用 drush updb 運行掛鉤。

- 檢查更新後的配置,新密鑰“描述”已更新。

使用 Post Update 掛鉤
Hook hook_post_update_NAME(),類似於update hook,用於引入更新。 但是這個鉤子主要用於更新數據,比如實體。 這些掛鉤在所有 hook_update_N() 掛鉤運行後執行。 在此階段,Drupal 已經完全修復,因此您可以在站點內使用任何 API。
這些掛鉤位於模塊中的 *.post_update.php 文件中。
hook_post_update_NAME() 的寫法是(模塊名稱)_post_update_(任意名稱)。 這裡的NAME可以是任意的機器名。 文件中函數的這種字母數字命名是確保此掛鉤執行順序的唯一因素。
與更新掛鉤類似,在 post_update 掛鉤之前的文檔塊註釋中添加適當的描述。 另外,不要重複使用相同的鉤子名稱。
hook_post_update_NAME() 的結構:
/** * A aimple hook_post_update_NAME() hook. */ function example_post_update_test() { // Code goes here. }
就像更新掛鉤一樣,使用 $sandbox 參數來指示 Batch API 應該用於您的 post_update 掛鉤。
使用更新後掛鉤更新術語數據的簡單示例:
- 目前,標籤詞彙表下的所有術語都有一個禁用的“測試示例”字段。

- 在 example_module.post_update.php 文件中添加一個 post_update 掛鉤,為所有現有術語啟用“測試示例”字段。

- 使用 drush updb 運行掛鉤。

- 驗證更新的術語數據,必須啟用複選框“測試示例”。

如何運行這些鉤子!
您可以使用 Drush 命令執行這些掛鉤,drush updb。它按以下步驟構建批處理:
- 發現所有更新掛鉤。
- 解決依賴關係並對它們的順序進行排序。
- 放置鉤子用於批處理。
- 接下來,發現所有 Post 掛鉤。
- 如果有 post_update 掛鉤,並且 update_hook 之前運行過,則緩存被清除。
- 然後,將每個 post_update 掛鉤推送到批處理中。
- 執行批處理。
post-update hook 相對於 update hook 的一個主要優勢是 Drupal 在運行 post-update 時功能齊全。 這允許開發人員在使用更新後掛鉤的同時使用任何 Drupal 服務。 使用更新掛鉤,不能假設 Drupal 已完全修復並避免調用其他掛鉤、實體 API 等。
最後的想法
當嘗試通過更新配置/數據庫架構來修復您的站點時,請嘗試使用更新掛鉤。 當涉及到操作存儲的數據、重新保存配置、更新內容實體、清除緩存等時,更新後掛鉤更適合使用。
老實說,Drupal.org 上沒有關於何時使用哪個鉤子的明確文檔! 有一個未解決的問題要求改進關於這兩個鉤子的使用的文檔,如果你願意,你可以貢獻它。
但是根據開發者的經驗,以Drupal 9 & 10核心模塊為例,使用update hooks對配置或數據庫執行CRUD操作(即修復站點),使用post-update hooks對CRUD內容實體(然後修復更新站點上的數據),因為更新後掛鉤在更新掛鉤之後運行。
喜歡閱讀這篇文章嗎? 向我們表達愛意並訂閱我們的每週時事通訊!