arhone/commutation

用于启动事件处理器的库 (PHP 7)

1.0.1 2017-10-30 09:58 UTC

This package is not auto-updated.

Last update: 2024-09-29 05:49:22 UTC


README

触发器 (PHP 7)

触发器允许基于其他事件创建事件应用程序。

与路由器不同,触发器创建的关联不仅是一对一,还是一对多。

触发器的工作原理非常简单

  1. 添加某个事件的处理器
  2. 启动该事件
  3. 处理器执行

可以为同一事件添加任意多的处理器,在这种情况下,它们将顺序处理您的请求。

触发器可以在各种任务中发挥作用,例如

  1. 根据不同的地址输出网站的不同内容。作为事件,您指定页面URI,特定页面的处理器返回特定结果。
  2. 处理来自控制台、cron或通过其他应用程序API(例如telegram)的命令。当服务器收到命令时,处理器会对其做出反应。
  3. 创建钩子。例如,可以启动有关添加新新闻或服务器上上传了新文件的事件。将来可以编写处理这些事件的代码,例如,在添加新闻时清除最新新闻块缓存,在上传图像时添加水印。
  4. 记录/跟踪。假设您正在构建文档处理系统,并且需要发送通知,如果用户已阅读文档。
  5. 限制访问。如果用户未认证,则显示认证表单。
  6. 还有更多。

安装

composer require arhone/commutation

<?php
use arhone\commutation\trigger\Trigger;

include 'vendor/autoload.php';

$trigger = new Trigger();

示例

<?php

// Добавляем обработчик на определённое событие
$trigger->add('событие', function () {
    return 'ответ';
});

// Запускаем событие
echo $trigger->run('событие'); // ответ

// триггером для запуска обработчика послужил запуск события $trigger->run('событие')
触发器理解正则表达式

处理器接收三个参数

  1. $match - 匹配数组
  2. $data - run 方法的第二个参数传递的数据
  3. $option - 设置数组
<?php

// Добавляем обработчик
$trigger->add('switch:(on|off)', function ($match, $data, $option) {

    if ($match[1] == 'on') {
        return $data . ' - Включен';
    } else {
        return $data . ' - Отключен';
    }

});

// Запускаем событие
echo $trigger->run('switch:on', 'Чайник'); // Чайник - Включен
注册多个处理器

前一个处理器的响应将被传递给下一个处理器作为 $data

<?php

// Добавляем обработчик
$trigger->add('switch:(on|off)', function ($match, $data) {
    return 'Самовар';
});

// Добавляем обработчик
$trigger->add('switch:(on|off)', function ($match, $data) {

    if ($match[1] == 'on') {
        return $data . ' - Включен';
    } else {
        return $data . ' - Отключен';
    }

});

// Запускаем событие
echo $trigger->run('switch:on', 'Чайник'); // Самовар - Включен
处理器可以是“中断的”

如果中断处理器的处理程序返回非 null,则中断当前事件的处理堆栈。

为了创建中断处理器,需要将 (break) 参数设置为 true

<?php

// Добавляем обрывающий обработчик
$trigger->add('switch:(on|off)', function ($match, $data) {

    $energy = false;
    if (!$energy) {
        return 'Нет электричества';
    }

}, [
    'break' => true
]);

// Добавляем обработчик
$trigger->add('switch:(on|off)', function ($match, $data) {

    if ($match[1] == 'on') {
        return $data . ' - Включен';
    } else {
        return $data . ' - Отключен';
    }

});

// Запускаем событие
echo $trigger->run('switch:on', 'Чайник'); // Нет электричества
队列位置

使用数组 $option 可以指定处理器的启动顺序。

建议的值为 -1 到 1(默认 0)

因此,使用 -1 可以将处理器的执行放置在开始,使用 1 可以将其放置在末尾。

使用 $trigger->plan() 方法而不是 $trigger->run() 来查看处理器的启动顺序。

<?php

$trigger->add('hello', function ($match, $data) {
    return $data . ' дорогой';
}, [
    'name'     => 'Второй обработчик',
    'position' => 0.2
]);

$trigger->add('hello', function ($match, $data) {
    return $data . ' мой';
}, [
    'name'     => 'Первый обработчик',
    'position' => 0.1
]);

$trigger->add('hello', function ($match, $data) {
    return $data . ' друг';
}, [
    'name'     => 'Третий обработчик',
    'position' => 0.3
]);

echo $trigger->run('hello', 'Привет'); // Привет мой дорогой друг

print_r($trigger->plan('hello'));
命名处理器

可以为处理器指定一个唯一的名称。

如上例所示,名称有助于在“plan”方法中使用时识别处理器。

还可以通过名称覆盖另一个处理器的选项。

<?php

$trigger->add('test', function ($match, $data) use ($trigger) {

    $trigger->option('two', [
        'status' => false // Второй обработчик не будет запущен
    ]);

    return 'Первый';

}, [
    'name' => 'one',
]);

$trigger->add('test', function ($match, $data) {
    return 'Второй';
}, [
    'name' => 'two',
]);

echo $trigger->run('test'); // Первый
启用/禁用处理器

“status”选项允许禁用不需要的处理器。

<?php

$trigger->add('start', function ($match, $data) {
    return $data . ' раз';
});

$trigger->add('start', function ($match, $data) {
    return $data . ' два';
});

$trigger->add('start', function ($match, $data) {
    return $data . ' три';
}, [
    'status' => false
]);

echo $trigger->run('start'); // раз два

更多示例

管理路由(Router)

触发器可以用于处理路由。

您可以自己定义请求模板,例如,对于通过Web服务器发出的请求,可以指定 HTTP:TYPE:path,对于通过控制台发出的请求,可以指定 console:command。

<?php

$trigger->add('(http[s]?):get:/home.html', function () {
    return 'hello word'; 
});

// Пользователь зашёл по HTTP типа GET на страницу /home.html
echo $trigger->run('http:get:/home.html');
<?php

$trigger->add('console:cache-clear', function () {
    return 'Кэш очищен';
});

echo $trigger->run('console:cache-clear');

实现中间件(Middleware)

<?php

// Проверяем если пользователь не авторизован
$trigger->add('http:get:/home.html', function () {
    if (User::id() == false) {
        return 'Нужно авторизироваться';
    }
}, [
    'break' => true
]);

// Или выводим приветствие
$trigger->add('http:get:/home.html', function () {
    return 'Привет'; 
});

// Пользователь зашёл по HTTP типа GET на страницу /home.html
echo $trigger->run('http:get:/home.html');

响应事件(Observer)

<?php

// Очищаем кэш новостей
$trigger->add('module:news:add', function () {
    Cache::clear('module:news');
});

// Событие что была добавлена новость с id 100
$trigger->run('module:news:add', [
    'id' => 100
]);

处理请求。

<?php

// Пишем кэш в Redis
$trigger->add('cache:set', function ($match, $data) {
    CacheRedis::set($data['key'], $data['value']);
});

// Пишем в файл на всякий случай
$trigger->add('cache:set', function ($match, $data) {
    CacheFile::set($data['key'], $data['value']);
});

// Генерируем команду на запись в кэш
$trigger->run('cache:set', [
    'key'   => 'ключ',
    'value' => 'данные для кэширования'
]);
<?php

// Берём кэш из редиса, если сервер редиса доступен
$trigger->add('cache:get', function ($match, $data) {
    if (CacheRedis::status() == true) {
        return CacheRedis::get($data['key']);    
    }
}, [
    'break' => true
]); // Параметр break, остановит стек, если обработчик что-то вернул (не null)

// Если редис ничего не вернул, то запустится следующий обработчик и вернёт кэш из файла
$trigger->add('cache:get', function ($match, $data) {
   if (CacheFile::status() == true) {
       return CacheFile::get($data['key']);
   }
});

// Генерируем команду на получение кэша
$trigger->run('cache:get', [
    'key' => 'ключ'
]);

通过处理器堆栈处理数据。

<?php

$trigger->add('hello', function ($match, $data) {
    return $data . ' мой';
});

$trigger->add('hello', function ($match, $data) {
    return $data . ' дорогой';
});

$trigger->add('hello', function ($match, $data) {
    return $data . ' друг';
});

echo $trigger->run('hello', 'Привет'); // Привет мой дорогой друг