## 组件 组件是 MixPHP 的核心设计思想,整个框架都是由众多核心组件构成。 | 类 | | --- | | Mix\Core\Component\AbstractComponent | >[success] 用户可通过自定义组件将频繁调用的业务代码常驻于内存,达到更高的性能。 组件的核心特征: - 常驻内存 - 事件 - 协程隔离 >[danger] 请谨慎注册太多组件,组件应该是全局使用的,使用频繁的。 ## 创建一个组件 你只需继承 `Mix\Core\Component\AbstractComponent` 抽象类就可以了,由于组件类继承自 `Mix\Core\Bean\AbstractObject` 所以组件都是通过依赖注入实例化的。 下面是一个组件范例: ~~~php <?php namespace Http\Components; use Mix\Core\Component\AbstractComponent; class MyComponent extends AbstractComponent { // 名称 public $name; public function hello() { echo 'hello, ', $this->name; } } ~~~ ## 组件注册 所有组件都是在应用配置内的 `components` 字段内注册, 下面是一个自定义组件的注册配置: ~~~ // 组件配置 'components' => [ 'myComponent' => [ // 依赖引用 'ref' => beanname(Http\Components\MyComponent::class), ], ], // 依赖配置 'beans' => [ [ // 类路径 'class' => Http\Components\MyComponent::class, // 属性 'properties' => [ // 名称 'name' => '小明', ], ], ], ~~~ - `myComponent` 为组件名称,调用时使用。 - `ref` 为引用的依赖名称,beanname 方法将类名转换为依赖名称。 ## 如何调用组件 组件在框架内任何位置都可使用,包括:控制器、模型、自定义类、第三方类。 ~~~php app()->myComponent->hello(); ~~~ ## 为组件增加 IDE 代码补全 找到 `applications/common/src/ApplicationInterface.php` ,在 PHP 注释参数中增加: ``` @property \Httpd\Components\MyComponent $myComponent ``` >[info] MixPHP 框架几乎全部代码都有完善的 IDE 代码补全支持,包括用户自定义类,也提供了增加补全的方法。 ## 组件的事件 由于组件是常驻内存的,请求结束后不会销毁,而有些特殊情况下需要对请求周期内做一些初始化、数据清理方面的处理,所以 MixPHP 设计了事件机制,提供下面两个请求级别的事件函数: - onBeforeInitialize:服务器回调事件开始时触发,用于请求开始的初始化处理。 - onAfterInitialize:服务器回调事件结束时触发,用于请求结束的数据清理。 >[info] 已上事件代码内没有调用的组件不会触发。 使用时只需在组件内重写这几个事件方法即可。 ~~~php // 前置初始化事件 public function onBeforeInitialize() { parent::onBeforeInitialize(); // ... } // 后置初始化事件 public function onAfterInitialize() { parent::onAfterInitialize(); // ... } ~~~ ## 组件的协程模式 框架实现了组件的协程隔离,用户可在协程的任意位置使用组件,但用户如果自己定义组件,需要了解组件的协程模式机制。 ### 协程模式 组件的协程模式决定组件在新的协程中获取实例的方式: - 新建模式 (默认):`ComponentInterface::COROUTINE_MODE_NEW` 当在启动一个新的顶级协程时通过依赖配置新建一个组件类,执行 `onBeforeInitialize`,当该顶级协程内的最后一个子协程执行完成该组件类将被销毁,执行 `onAfterInitialize`。 - 引用模式:`ComponentInterface::COROUTINE_MODE_REFERENCE` 在任意协程内都将获取同一个全局实例,该类型的组件不执行 `onBeforeInitialize`、`onAfterInitialize` 事件。 ## 第三方类库设置为组件 >[danger] 由于 Swoole 为常驻程序,所有使用全局变量的库,都有可能存在变量污染问题而无法设置为组件,特别是在协程模式。 通过使用 `Mix\Core\Component\ComponentTrait` 手动处理第三方的类的依赖注入,代码如下: ~~~php class MyComponent extends ThirdClass implements \Mix\Core\Component\ComponentInterface, ComponentInterface { use Mix\Core\Component\ComponentTrait; // 如果需要接收配置,可以在这里手动处理,$config 就是传入的配置信息 public function __construct($config = []) { parent::__construct(); } } ~~~ 然后将这个类注册到组件配置 `components` 下即可。