phata/hook

基于PHP的接口特性和PSR-11容器的最小化钩子库。

v1.1.0 2018-09-19 09:14 UTC

This package is auto-updated.

Last update: 2024-09-27 10:17:54 UTC


README

build status latest stable version total downloads total downloads

基于PHP的接口特性和PSR-11容器的最小化钩子库。

为什么

许多CMS(如DrupalWordpress)基于钩子系统进行模块化。它们通常是这样工作的

  1. CMS在其文档中某处声明钩子。
  2. 并提供一种方式让模块声明它们实现了任何钩子。
  3. 模块按照文档实现钩子。
  4. 在CMS中某个地方,当钩子“调用”时,从(3)中收集所有实现并针对某些数据进行运行。收集返回值。

它们通常也允许模块声明自己的钩子。但它们需要自己实现(4)。CMS会提供辅助API来调用钩子。

此库提供了一种现代方式来实现。

安装

推荐方法是使用composer

composer require "phata/hook"

然后您应该能够使用composer的自动加载

示例用法

基本的调用映射和归约```php // composer的自动加载器路径 require_once '../vendor/autoload.php'; $container = new DI\Container; // 或其他PHP-11兼容的容器 $registry = new Phata\Hook\Registry; $invoker = new Phata\Hook\Invoker($registry, $container); // 将现有接口声明为钩子。 $registry->declareHooks([ App\MyInterface::class, SomeAwesomeLibrary\Interface::class, ]); // 将类添加到注册表中,它会自动针对声明的钩子进行索引。 $registry->add([ App\MyModule1::class, App\MyModule2::class, FooBar\External\Module::class, ]); // 使用$invoker来调用钩子 // 使用1:映射结果 $array = $invoker->map( App\MyInterface::class, function (App\MyInterface $module) { return $module->doSomething(); } ); // 使用2:归约 $result = $invoker->reduce( App\MyInterface::class, function ($carry, App\MyInterface $module) { return $module->process($carry); }, $someInitialValue ); ```

高级示例

使用排序调用者有序模块```php nameapace App; use Phata\Hook\SortableInterface; class MyModule1 implements SortableInterface, MyInterface { public function myProcess($input) { // 对$input的一些处理 // ... return $output; } public function getWeight():int { // 获取模块权重的一些逻辑 // 可能来自数据库操作 // ... return $weight; } } ``` ```php // composer的自动加载器路径 require_once '../vendor/autoload.php'; $container = new DI\Container; // 或其他PHP-11兼容的容器 $registry = new Phata\Hook\Registry; $invoker = new Phata\Hook\SortingInvoker($registry, $container); // 将现有接口声明为钩子。 $registry->declareHooks([ Psr\Http\Server\MiddlewareInterface::class, ]); // 将类添加到注册表中,它会自动针对声明的钩子进行索引。 $registry->add([ App\MyModule1::class, App\MyModule2::class, FooBar\External\Module::class, ]); // 处理请求 // // 注意:排序调用者将在调用之前根据权重排序模块。 $results = $invoker->map( App\MyInterface::class, function (App\MyInterface $module) use ($input) { return $module->process($input); } ); // 使用$results //... ```
使用PSR-7请求与PSR-15中间件进行消费```php // composer的自动加载器路径 require_once '../vendor/autoload.php'; $container = new DI\Container; // 或者其他PHP-11兼容的容器 $registry = new Phata\Hook\Registry; $invoker = new Phata\Hook\Invoker($registry, $container); // 声明现有接口为钩子。 $registry->declareHooks([ Psr\Http\Server\MiddlewareInterface::class, ]); // 将类添加到注册表中,它会自动针对声明的钩子进行索引。 $registry->add([ App\MyModule1::class, App\MyModule2::class, FooBar\External\Module::class, ]); // 处理请求 $request = $invoker->reduce( Psr\Http\Server\MiddlewareInterface::class, function ($request, Psr\Http\Server\MiddlewareInterface::class $middleware) { return $middleware->process($request); }, GuzzleHttp\Psr7\ServerRequest::fromGlobals() ); // 处理程序处理请求 //... ```
使用`$carry`聚合简化PSR-7请求```php // composer的自动加载器路径 require_once '../vendor/autoload.php'; $container = new DI\Container; // 或者其他PHP-11兼容的容器 $registry = new Phata\Hook\Registry; $invoker = new Phata\Hook\Invoker($registry, $container); // 声明现有接口为钩子。 $registry->declareHooks([ App\Middleware\Interface::class, ]); // 将类添加到注册表中,它会自动针对声明的钩子进行索引。 $registry->add([ App\MyModule1::class, App\MyModule2::class, FooBar\External\Module::class, ]); // 处理请求 $request = GuzzleHttp\Psr7\ServerRequest::fromGlobals(); $result = $invoker->reduce( App\Middleware\Interface::class, function ($carry, App\Middleware\Interface::class $middleware) use ($request) { $middleware->process($carry, $request); return $carry; }, null ); ```

文档

Phata\Hook的类和类型文档可以在这里找到。

许可

Phata\Hook遵循MIT许可协议分发。您应该已经收到了Phata/Hook附带的GNU Lesser General Public License副本。如果没有,请参阅https://open-source.org.cn/licenses/MIT