☰
Hyperf 元件開發指南:使用官方工具建立元件包並在專案中引入未釋出的元件
2026/10/10 1:56:39 网站建设 项目流程
  • 后端
  • 微服务

【免费下载链接】hyperf

🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.

项目地址:https://gitcode.com/gh_mirrors/hy/hyperf
点击查看免费下载

Hyperf 是一個基於 Swoole/Swow 的高效能協程框架,其生態的核心在於「元件化」設計——幾乎所有能力都以獨立元件的形式提供,開發者也可以開發自己的元件來擴充套件框架、共建生態。本文聚焦元件開發的第一步:如何使用官方提供的hyperf/component-creator工具快速搭建元件包骨架,以及如何在專案中透過 Composer 的path倉庫來源引入尚未釋出到 Packagist 的元件,並結合當前倉庫的原始碼講解元件被框架識別與載入的底層機制。讀完本文,你將掌握「從零建立元件包 → 本地開發調試 → 配置釋出」的完整閉環。

元件開發的前置認知

在動手建立元件之前,有必要先理解 Hyperf 元件化開發的定位。與傳統 PHP-FPM 架構下「透過 Composer 直接引入一個庫(Library)」的模式不同,Hyperf 具備持久化應用與協程兩個特性,導致應用生命週期與執行模式存在較大差異,因此並非所有第三方庫都能在 Hyperf 中直接使用。元件開發指南的前言明確指出:在閱讀本指南前,建議先全面閱讀 協程 與 依賴注入 章節,對 Hyperf 的基礎元件有充分理解後再開始元件開發。

元件開發的核心思想是:元件自身保持「低耦合、高獨立、可重用」,元件之間的解耦依賴於ConfigProvider機制——每個元件提供一個ConfigProvider類,在框架啟動時被載入並合併到全域配置中,完成元件的配置初始化。關於該機制的完整說明,可參閱 ConfigProvider 機制,下文也會結合原始碼展開。

使用官方工具建立新的元件包

Hyperf官方提供了hyperf/component-creator工具來快速建立元件包,這是元件開發的最簡潔起點。透過composer create-project即可生成一個適配目標版本、結構完整的元件骨架:

# 建立適配 Hyperf 最新版本的元件包 composer create-project hyperf/component-creator your_component dev-master # 建立適配 Hyperf 2.0 版本的元件包 composer create-project hyperf/component-creator your_component "2.0.*"

其中your_component是元件包的目錄名(同時也應作為包名的一部分),dev-master或"2.0.*"用於指定建立工具自身對應的版本分支,從而生成與目標 Hyperf 主版本匹配的元件骨架。

從當前倉庫的實際結構看,一個標準元件包通常具備以下形態(以hyperf/amqp為例):

  • src/:PSR-4 自動載入的原始碼目錄,包含元件核心類;
  • publish/:元件預設配置檔案目錄(如 publish 配置),用於後續vendor:publish釋出;
  • tests/:單元測試目錄;
  • composer.json:元件描述檔案,其中extra.hyperf.config指向元件根目錄下的ConfigProvider類;
  • ConfigProvider.php:元件配置提供者,位於元件根目錄。

在專案中使用未釋出的元件包

元件建立完成後、正式釋出到 Packagist 之前,你可能需要在實際專案中先行使用、調試。Composer 原生支援path型別的倉庫來源,可以將本地目錄作為依賴來源引入,這正是 Hyperf 官方文件推薦的本地開發方案。

假設專案目錄結構如下:

/opt/project // 專案目錄 /opt/your_component // 元件包目錄

假設元件名為your_component/your_component,則需修改/opt/project/composer.json(以下省略其他不相干的配置):

{ "require": { "your_component/your_component": "dev-master" }, "repositories": { "your_component": { "type": "path", "url": "/opt/your_component" } } }

最後在目錄/opt/project中執行composer update -o即可完成依賴更新。-o(即--optimize-autoloader)會在更新依賴的同時優化自動載入器,將 PSR-4 等規則轉換為更高效的 classmap,在 path 倉庫場景下能保證本地元件的類被準確、快速地載入。

這種path來源的寫法同樣適用於開發 Hyperf 自身元件:在指南前言中,官方建議在同一目錄下分別安裝hyperf/hyperf-skeleton骨架專案與hyperf/hyperf元件庫,並在骨架專案的composer.json中將repositories指向../hyperf/src/*,這樣vendor/hyperf下的元件目錄全部以軟連結(softlink)方式指向原始碼目錄,開發者可以在 IDE 中直接修改vendor/hyperf內的檔案(實際修改的是原始碼),最終提交 PR 到主幹,實現「邊開發邊驗證」的工作流。

元件被框架識別的關鍵:ConfigProvider 與 composer.json 的 extra 配置

建立一個類並不會被 Hyperf 自動載入。元件要想在 Hyperf 框架啟動時被掃描、初始化,必須在元件的composer.json中宣告extra.hyperf.config,指定元件根目錄下ConfigProvider類的名稱空間:

{ "name": "hyperf/foo", "require": { "php": ">=7.3" }, "autoload": { "psr-4": { "Hyperf\\Foo\\": "src/" } }, "extra": { "hyperf": { "config": "Hyperf\\Foo\\ConfigProvider" } } }

定義之後需執行composer install或composer update或composer dump-autoload等會讓 Composer 重新生成composer.lock檔案的命令,才能被正常讀取。

為什麼必須重新生成composer.lock?從原始碼可以看出端倪:Composer 工具類中的getMergedExtra()方法會先透過getLockContent()讀取專案根目錄下的composer.lock,解析出所有已安裝包的extra欄位(src/support/src/Composer.php):

public static function getMergedExtra(?string $key = null): array { if (! self::$extra) { self::getLockContent(); } // 將所有包 extra 中指定 key 的配置按規則合併 // 陣列值使用 array_merge 合併,非陣列值以追加方式收集 ... }

也就是說,框架是從composer.lock的packages/packages-dev中提取每個包的extra資訊(src/support/src/Composer.php),因此只有執行上述任一命令讓composer.lock包含新元件的extra欄位後,元件才能被框架感知。

以倉庫內真實元件hyperf/amqp為例,其 composer.json 中宣告:

"extra": { "branch-alias": { "dev-master": "3.2-dev" }, "hyperf": { "config": "Hyperf\\Amqp\\ConfigProvider" } }

而 Hyperf\Amqp\ConfigProvider 則返回了該元件的依賴綁定、事件監聽器與待釋出配置等完整資訊:

class ConfigProvider { public function __invoke(): array { return [ 'dependencies' => [ Producer::class => Producer::class, Packer::class => JsonPacker::class, Consumer::class => ConsumerFactory::class, ], 'listeners' => [ BeforeMainServerStartListener::class => 99, MainWorkerStartListener::class, ], 'publish' => [ [ 'id' => 'config', 'description' => 'The config for amqp.', 'source' => __DIR__ . '/../publish/amqp.php', 'destination' => BASE_PATH . '/config/autoload/amqp.php', ], ], ]; } }

由此可見,元件與框架的耦合被收斂到一個ConfigProvider類中,這正是「元件間解耦、元件獨立、元件可重用」的實現基礎。

ConfigProvider 的標準返回結構

ConfigProvider本身不具備任何依賴:不繼承抽象類、不要求實現介面,只需提供一個__invoke方法並返回一個配置結構陣列即可。其返回結構約定如下(完整範例見 ConfigProvider 機制):

<?php namespace Hyperf\Foo; class ConfigProvider { public function __invoke(): array { return [ // 合併到 config/autoload/dependencies.php 檔案 'dependencies' => [], // 合併到 config/autoload/annotations.php 檔案 'annotations' => [ 'scan' => [ 'paths' => [ __DIR__, ], ], ], // 預設 Command 的定義,合併到 Hyperf\Contract\ConfigInterface 內,與 config/autoload/commands.php 對應 'commands' => [], // 事件監聽器,與 commands 類似 'listeners' => [], // 元件預設配置檔案,執行 vendor:publish 命令後會把 source 對應的檔案複製為 destination 對應的檔案 'publish' => [ [ 'id' => 'config', 'description' => 'description of this config file.', // 描述 // 建議預設配置放在 publish 資料夾中,檔案命名和元件名稱相同 'source' => __DIR__ . '/../publish/file.php', // 對應的配置檔案路徑 'destination' => BASE_PATH . '/config/autoload/file.php', // 複製為這個路徑下的該檔案 ], ], // 亦可繼續定義其它配置,最終都會合併到與 ConfigInterface 對應的配置儲存器中 ]; } }

需要注意的是,ConfigProvider的配置並非一定就是這樣劃分,這些只是約定俗成的格式,實際上最終如何解析這些配置的決定權在於使用者——可透過修改 Skeleton 專案的config/container.php檔案內的程式碼來調整相關載入,也就是說config/container.php決定了ConfigProvider的掃描與載入方式。

透過 vendor:publish 釋出元件預設配置

在ConfigProvider中定義好publish後,可以使用如下命令快速生成配置檔案:

php bin/hyperf.php vendor:publish 包名稱

例如包名稱為hyperf/amqp,可執行命令生成amqp預設的配置檔案:

php bin/hyperf.php vendor:publish hyperf/amqp

該命令的底層實現位於 VendorPublishCommand。從原始碼可以看出其完整行為(src/devtool/src/VendorPublishCommand.php):

  • package(必填參數):要釋出配置的包名稱;
  • -i, --id(可選):指定要釋出的配置項id,僅釋出該項;
  • -s, --show(可選):列出該包所有可釋出的配置項,不實際複製;
  • -f, --force(可選):覆蓋已存在的目標檔案(預設若目標檔案已存在會跳過並提示[destination] already exists.)。

命令執行時,會透過Composer::getMergedExtra()從composer.lock中讀取該包的extra.hyperf.config,實例化對應的ConfigProvider並呼叫__invoke()取得配置陣列,再取出publish項逐個複製(src/devtool/src/VendorPublishCommand.php)。複製過程中,若目標目錄不存在會自動建立(權限 0755),若source是目錄則執行目錄複製,否則執行單檔案複製——這意味著publish不僅可以釋出單個配置檔案,也可以釋出整個目錄(例如模板、遷移檔案等)。

publish 項的欄位說明

欄位說明
id配置項的唯一識別符,供vendor:publish -i精確指定使用
description該配置項的描述文字
source元件內預設配置檔案的路徑,建議放在publish/資料夾,檔案命名與元件名稱相同
destination複製到專案中的目標路徑,通常為BASE_PATH . '/config/autoload/xxx.php'

元件設計規範

由於composer.json內的extra屬性在資料不被利用時沒有其它作用和影響,因此元件內的這些定義在其它框架使用時不會造成任何干擾,ConfigProvider是一種僅作用於 Hyperf 框架的機制,這為元件的複用打下了基礎。但這也要求在進行元件設計時,必須遵循以下規範(詳見 ConfigProvider 機制):

  • 所有類的設計都必須允許透過標準OOP方式使用,所有 Hyperf 專有功能必須作為增強功能並以單獨的類提供,也就是說在非 Hyperf 框架下仍能透過標準手段使用元件;
  • 元件的依賴設計優先滿足 PSR 標準);
  • 對於實現 Hyperf 專有功能所增加的增強功能類,通常會依賴 Hyperf 的一些元件,這些依賴不應寫在composer.json的require項,而應寫在suggest項作為建議項(如 amqp 的 composer.json 中將hyperf/di、hyperf/event列為suggest);
  • 元件設計時不應該透過註解進行任何依賴注入,注入方式應只使用建構函式注入,這樣同時也能滿足在 OOP 下的使用;
  • 元件設計時不應該透過註解進行任何功能定義,功能定義應只透過ConfigProvider來定義;
  • 類的設計時應盡可能不儲存狀態資料,因為這會導致類不能作為長生命週期物件提供,也無法方便地使用依賴注入,會在一定程度下降低效能;狀態資料應透過Hyperf\Context\Context協程上下文來儲存。

結語

至此,你已經掌握了元件開發的完整起步路徑:用hyperf/component-creator建立元件骨架 → 透過 Composerpath倉庫在本地專案中引入未釋出元件進行聯調 → 用ConfigProvider定義元件配置與釋出項 → 透過vendor:publish向使用者專案釋出預設配置。在此基礎上,進一步閱讀 ConfigProvider 機制 與 指南前言(包含透過軟連結直接開發 Hyperf 自身元件的進階工作流),即可完整掌握 Hyperf 元件開發的規範與生態共建方式。

  • 后端
  • 微服务

【免费下载链接】hyperf

🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.

项目地址:https://gitcode.com/gh_mirrors/hy/hyperf
点击查看免费下载

相关推荐

上一篇:使用 OPA 实现 Docker 细粒度授权:opa-docker-authz 插件接入实战指南
下一篇:js-bson完全指南:从安装到精通的Binary JSON解析利器

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询