## 组件 组件是 MixPHP 的核心设计思想,整个框架都是由众多核心组件构成。 | 类 | | --- | | mix\base\Component | >[success] 通过用户可自定义组件、组件常驻内存这两个特性 MixPHP 能让用户将频繁调用的业务代码也可常驻于内存,达到更高的性能。 组件的核心特征: - 常驻内存 - 事件 - 协程隔离 >[danger] 请谨慎注册太多组件,组件应该是全局使用的,使用频繁的。 ## 创建一个组件 你只需继承 `\mix\base\Component` 类,就可以了,下面是一个范例: ~~~php <?php namespace apps\index\components; use \mix\base\Component; class MyComponent extends Component { public $name; public function hello() { echo 'hello, ', $this->name; } } ~~~ ## 组件注册 所有组件都是在应用配置内的 `components` 字段内注册,下面是一个自定义组件的注册配置: ~~~php // 组件配置 'components' => [ // 普通命名 'myComponent' => [ // 类路径 'class' => 'apps\index\components\MyComponent', // 属性 'name' => '小花', ], // 带前缀的名称 'prefix.myComponent' => [ // 类路径 'class' => 'apps\index\components\MyComponent', // 属性 'name' => '小花', ], // 带多级前缀的名称 'prefix.prefix.myComponent' => [ // 类路径 'class' => 'apps\index\components\MyComponent', // 属性 'name' => '小花', ], ], ~~~ - myComponent 是组件名称,调用时使用。 - class 需要实例化类的命名空间。 - 其他字段:都会在该类实例化后,导入为对象属性,key为属性名称,value为属性的值。 [>> 到 GitHub 查看默认组件配置 <<](https://github.com/mixstart/mixphp/blob/master/apps/httpd/config/http_permanent.php#L18) ## 如何调用组件 在框架内任何位置都可使用,包括:控制器、模型、自定义类、第三方类。 ~~~php // 普通命名 app()->myComponent->hello(); // 带前缀的名称 app('prefix')->myComponent->hello(); // 带多级前缀的名称 app('prefix.prefix')->myComponent->hello(); ~~~ MixPHP 支持两种运行模式,不同模式下组件初始化的方式不同: - mix-httpd:全部组件在服务器启动时已经加载完成。 - Apache/PHP-FPM:懒加载,只有调用 `app()->[ComponentName]` 时组件才会加载。 ## 组件的事件 由于组件是常驻内存的,请求结束后不会销毁,而有些特殊情况下需要对请求周期内做一些初始化、数据清理方面的处理,所以 MixPHP 设计了事件机制,提供下面两个请求级别的事件函数: - onRequestBefore:每次请求开始时触发,用于请求级别的初始化处理(代码内没有调用的组件不会触发)。 - onRequestAfter:每次请求结束时触发,用于请求结束后组件数据清理(代码内没有调用的组件不会触发)。 使用时只需在组件内重写这几个事件方法即可。 ~~~php // 请求前置事件 public function onRequestBefore() { parent::onRequestBefore(); // ... } // 请求后置事件 public function onRequestAfter() { parent::onRequestAfter(); // ... } ~~~ 由于 `\mix\base\Component` 类继承了 `mix\base\BaseObject` 类,所以还包含三个事件: - onConstruct:构造事件,相当于 __construct 方法。 - onInitialize:当组件完成构造事件并导入配置信息为属性后触发该事件,用于做一些初始化处理。 - onDestruct:析构事件,相当于 __destruct 方法。 使用时只需在组件内重写这几个事件方法即可。 ~~~php // 构造事件 public function onConstruct() { parent::onConstruct(); // ... } // 初始化事件 public function onInitialize() { parent::onInitialize(); // ... } // 析构事件 public function onDestruct() { parent::onDestruct(); // ... } ~~~ ## 直接将第三方类库设置为组件 `Trait` >[danger] 由于 Swoole 为常驻程序,所有使用全局变量的库,都有可能存在变量污染问题而无法设置为组件,特别是在协程模式。 用户只需新增一个类,继承第三方类库,实现 `mix\base\ComponentInterface`,`mix\base\StaticInstanceInterface` 接口,并引用 `mix\base\StaticInstanceTrait`、`mix\base\ComponentTrait` 即可。 代码如下: ~~~php class MyComponent extends ThirdClass implements StaticInstanceInterface, ComponentInterface { use StaticInstanceTrait, ComponentTrait; // 如果需要接收配置,可以在这里手动处理,$config 就是传入的配置信息 public function __construct($config = []) { parent::__construct(); } } ~~~ 然后将这个类注册到组件配置 `components` 下即可。