mouadziani/xstate

状态机库,用于处理PHP对象的任何复杂行为

1.0.1 2022-07-17 14:43 UTC

This package is auto-updated.

Last update: 2024-09-08 22:06:23 UTC


README

xstate php logo

XState - PHP的状态机

XState 是一个 状态机 库,可以处理PHP对象的任何复杂行为(灵感来自 xstate.js

安装

建议通过 Composer 安装 Xstate

composer require mouadziani/xstate

定义状态机工作流程

Video state machine diagram

假设我们想为视频对象定义一个状态机工作流程,通常视频可能有3个状态(播放、停止、暂停),

第一步,您需要从 StateMachine 类创建一个新的对象

use \Mouadziani\XState\StateMachine;

$video = StateMachine::make();

然后,您需要定义允许的状态以及默认状态

$video
    ->defaultState('stopped')
    ->states(['playing', 'stopped', 'paused']);

最后,定义转换

use \Mouadziani\XState\Transition;

$video->transitions([
    new Transition('PLAY', ['stopped', 'paused'], 'playing'),
    new Transition('STOP', 'playing', 'stopped'),
    new Transition('PAUSE', 'playing', 'paused'),
    new Transition('RESUME', 'paused', 'playing'),
]);

Transition 类期望3个必需参数

  • 触发器:作为转换的名称,该名称将用于触发特定的转换 (应该是唯一的)
  • :期望一个字符串,用于单个状态,或数组,用于多个初始允许状态
  • :期望一个字符串,表示下一个目标状态 (应与定义的允许状态之一匹配)

守卫(可选)

您可以使用 guard 方法为特定的转换定义一个守卫回调函数,该回调函数必须返回一个布尔值。如果守卫返回 false,则无法执行转换。

use \Mouadziani\XState\Transition;

$video->transitions([
    (new Transition('PLAY', ['stopped', 'paused'], 'playing'))
        ->guard(function ($from, $to) {
            return true;
        })
]);

💡 您可以使用单个语句定义整个工作流程

$video = StateMachine::make()
    ->defaultState('playing')
    ->states(['playing', 'stopped', 'paused'])
    ->transitions([
        new Transition('PLAY', ['stopped', 'paused'], 'playing'),
        new Transition('STOP', 'playing', 'stopped'),
        new Transition('PAUSE', 'playing', 'paused'),
    ]);

处理状态和转换

触发转换

有两种方式可以触发一个特定的定义好的转换

1- 使用 transitionTo 方法并指定转换的名称作为参数

$video->transitionTo('PLAY');

2- 或者直接调用机器对象中转换的名称作为方法

$video->play();

偶尔触发转换可能会抛出异常,如果目标转换未定义或不受允许

use \Mouadziani\XState\Exceptions;

try {
    $video->transitionTo('RESUME');
} catch (Exceptions\TransitionNotDefinedException $ex) {
    // the target transition is not defined
} catch (Exceptions\TransitionNotAllowedException $ex) {
    // the target transition is not allowed
}

获取当前状态

echo $video->currentState(); // playing

获取允许的转换

$video->allowedTransitions(); // ['STOP', 'PAUSE']

添加所需的转换

$video->addTransition(new Transition('TURN_OFF', 'playing', 'stopped'));

即将推出的功能

  • 添加为特定转换定义守卫的能力
  • 定义/处理触发转换前后的钩子

测试

composer test

安全漏洞

请查看我们的安全策略,了解如何报告安全漏洞:我们的安全策略

鸣谢

许可

MIT 许可证(MIT)。请参阅 许可文件 获取更多信息。

featured_repository