slaxweb/hooks

SlaxWeb 框架的 Hooks 库

0.6.0 2017-04-25 19:06 UTC

This package is not auto-updated.

Last update: 2024-09-14 16:24:13 UTC


README

Build Status

SlaxWeb/Framework 的 Hooks 组件,用于在常规应用执行中执行任意代码。即使组件主要用于 SlaxWeb/Framework,也可以在它之外使用。它作为 SlaxWeb/Logger 的附加组件。

为了方便使用,组件提供了一个 Factory 和 Service Provider 用于 Pimple/Container。

安装

最简单的安装方式是通过 composer,编辑你的 composer.json 文件以包含

{
    "require": {
        "slaxweb/hooks": "~0.5.*@dev"
    },
    "minimum-stability": "dev"
}

用法

本节将涵盖 Hooks 容器的实例化,以及向容器添加简单的钩子定义,以及执行这些定义,以及高级钩子定义的执行。

实例化

您不需要实例化 Logger 组件本身,但您必须实例化 Config 组件,并确保已加载 logger 配置,有关如何完成此操作,请参阅Logger 文档

当您实例化了依赖项后,使用方法非常简单

<?php
use SlaxWeb\Hooks\Container as Hooks;

require_once "vendor/autoload.php";

// instantiate Config object..

// initiate the Hooks container
$hooks = \SlaxWeb\Hooks\Factory::init($config);

// create a hook
$hook = \SlaxWeb\Hooks\Factory::newHook();
$hook->create("hook.name", function (Hooks $container) {
    // stuff..
    return "I ran!";
});

// add the hook to the container
$hook->addHook($hook);

// some app stuff

// execute the hook
if ($hooks->execute("hook.name") === "I ran!") {
    // stuff..
}

您可以使用 Pimple 依赖注入容器实现相同的功能,只需确保已注册所有 3 个组件的 Service Providers

  • SlaxWeb/Config
  • SlaxWeb/Logger
  • SlaxWeb/Hooks

当您注册了所有这三个提供者后,您就可以安全地使用 hooks 容器

<?php
use SlaxWeb\Hooks\Container as Hooks;

require_once "vendor/autoload.php":

$container = new Pimple\Container;

// register the providers
$container->register(new \SlaxWeb\Config\Service\Provider);
$container->register(new \SlaxWeb\Logger\Service\Provider);
$container->register(new \SlaxWeb\Hooks\Service\Provider);

// load the config for the logger etc.

$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container) {
    // stuff ..
    return "I ran!";
});

// add the hook to the container
$container["hooks.service"]->addHook($hook);

// some app stuff..

// execute the hook
if ($container["hook.service"]->exec("hook.name") === "I ran!") {
    // stuff..
}

多个钩子定义

如上所示,钩子执行方法将返回钩子定义的值。但单个钩子点可以包含多个定义。在这种情况下,exec 方法将返回所有返回值组成的数组,除非定义的返回值是 null。如果没有定义返回了有效的返回值,则 exec 方法将返回一个空数组。

为了更好地说明上述示例,请参阅下面的代码示例

// instantiation of everything required etc.

// create hooks
$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container) {
    return 1;
});
$container["hooks.service"]->addHook($hook);

$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container) {
    return null;
});
$container["hooks.service"]->addHook($hook);

$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container) {
    return 3;
});
$container["hooks.service"]->addHook($hook);

// execute the hook
$container["hooks.service"]->exec("hook.name"); // will return: [1, 2]

// create 'no return' hook
$hook = $container["newHook.factory"];
$hook->create("noreturn.hook", function (Hooks $container) {
    // stuff
});
$container["hooks.service"]->addHook($hook);

// execute the hook
$container["hooks.service"]->exec("noreturn.hook"); // will return: []

定义执行中断

除了每个钩子可以有多个定义外,钩子还可以阻止其他定义执行。在这种情况下,将容器实例传递给钩子定义作为第一个参数。每个钩子都可以调用传入容器对象上的 stopExec 方法,这将停止其他钩子定义的执行。

// create hooks
$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container) {
    $container->stopExec();
    return 1;
});
$container["hooks.service"]->addHook($hook);

$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container) {
    return 2;
});
$container["hooks.service"]->addHook($hook);

$container["hooks.service"]->exec("hook.name"); // will return: 1

钩子定义参数

当调用 exec 方法时,您可以向它传递额外的参数,所有这些参数都将传递给您的钩子定义。

// create hook
$hook = $container["newHook.factory"];
$hook->create("hook.name", function (Hooks $container, string $myParam) {
    return $myParam;
});
$container["hooks.service"]->addHook($hook);

$container["hooks.service"]->exec("hook.name", "foo"); // will return: "foo"