zinovyev / php-fsm
PHP 有限状态机
v0.6.5
2014-05-20 11:08 UTC
Requires
- php: >=5.4
This package is not auto-updated.
Last update: 2024-09-20 21:57:46 UTC
README
有限状态机允许您创建一个包含不同状态及其之间转换的对象,该对象可以根据当前状态改变其行为。
安装
要安装 FSM 机器,请使用 Composer。只需将以下内容添加到您的 composer.json 文件中
"require": { "zinovyev/php-fsm": "0.6.5" }
创建状态机步骤
- 创建状态类并定义状态
class StateA extends State { public function foo($name) { printf("Hello, %s!", $name); } }
- 创建一个新的 FSM\Client 实例(状态机)。
- 将您的状态绑定到客户端实例,应用事务并设置初始状态
class StateMachine extends Client { public function __construct() { parent::__construct(); /* ... */ $this ->addState($stateA) /* ... */ ->createTransition('fourth', 'stateA', 'stateB') /* ... */
或
$stateMachine = new Client; $stateMachine ->addState($stateA) ->addState($stateB) ->createTransition('fourth', 'stateA', 'stateB') ;
- 如果您想存储当前状态和参数并在稍后恢复它们,请使用 Memento
$memento = $stateMachine->createMemento();
并恢复
$stateMachine = new StateMachine(); $stateMachine->applyMemento($memento);
- 这就完成了!您简单的状态机现在已配置并准备好使用!
示例代码
<?php require_once('vendor/autoload.php'); use FSM\Client; use FSM\State\State; use FSM\State\StateInterface; /** * StateA class */ class StateA extends State { public function foo($f) { return $f; } } /** * StateB class */ class StateB extends State { public function bar($b) { return $b * 2; } } /** * StateC class */ class StateC extends State { public function fooBar($fb) { return strrev($fb); } public function shuffle(array $array) { shuffle($array); return $array; } } /** * StateMachine example class */ class StateMachine extends Client { public function __construct() { parent::__construct(); // Create StateA initial type instance of class StateA $stateA = new StateA(); $stateA->setName('stateA'); $stateA->setType(StateInterface::TYPE_INITIAL); // Create StateB finite type instance of class StateB $stateB = new StateB(); $stateB->setName('stateB'); $stateB->setType(StateInterface::TYPE_FINITE); // Create StateC regular type instance of class StateC $stateC = new StateC(); $stateC->setName('stateC'); $stateC->setType(StateInterface::TYPE_REGULAR); // Create StateD regular type instance of class StateB $stateD = new StateB(); $stateD->setName('stateD'); $stateD->setType(StateInterface::TYPE_REGULAR); // Attach states and transitions $this ->addState($stateA) ->addState($stateB) ->addState($stateC) ->addState($stateD) ->setInitialState($stateA) ->createTransition('initial', 'stateA', 'stateA') ->createTransition('second', 'stateA', 'stateC') ->createTransition('secondAlternative', 'stateA', 'stateD') ->createTransition('third', 'stateC', 'stateD') ->createTransition('thirdAlternative', 'stateD', 'stateC') ->createTransition('fourth', 'stateD', 'stateB') ->createTransition('fourthAlternative', 'stateC', 'stateB') ->createTransition('shortWay', 'stateA', 'stateB') ; } } // Create new StateMachine instance $stateMachine = new StateMachine(); $stateMachine->foo = 'bar'; // Add public property // Test StateA state printf("%d) State machine is at state: '%s'. Test function call result is: '%s'\n", 1, $stateMachine->getCurrentState()->getName(), // Get State Name $stateMachine->callAction('foo', $properties = [100]) // Call State function ); // Accept transition "initial" $stateMachine->acceptTransitionByName('initial'); printf("%d) State machine is at SAME state: '%s'. Test function call result: '%s'\n", 2, $stateMachine->getCurrentState()->getName(), // Get State Name $stateMachine->callAction('foo', $properties = [200]) // Call State function ); // Accept transition "second" $stateMachine->acceptTransitionByName('second'); printf("%d) State machine is at state: '%s'. Test function call result: '%s'\n", 3, $stateMachine->getCurrentState()->getName(), // Get State Name $stateMachine->fooBar('foo bar') // Call State function ); // Create a memento (snapshot) of the current state $memento = $stateMachine->createMemento(); // Unset StateMachine $stateMachine = null; unset($stateMachine); // Restore StateMachine from a snapshot (Memento) $stateMachine = new StateMachine(); $stateMachine->applyMemento($memento); printf("=*= Check property value after restore: \$foo='%s' =*=\n", $stateMachine->foo); // Accept transition "third" $stateMachine->acceptTransitionByName('third'); printf("%d) State machine is at state '%s'. Test function call result: '%s'\n", 4, $stateMachine->getCurrentState()->getName(), // Get State Name $stateMachine->bar(1) // Call State function ); // Accept transition "fourth" $stateMachine->acceptTransitionByName('fourth'); printf("%d) State machine is at state '%s'. Test function call result: '%s'\n", 5, $stateMachine->getCurrentState()->getName(), // Get State Name $stateMachine->bar(2) // Call State function );
示例代码执行结果
如果您在控制台中运行此代码,您将看到以下输出:
1) State machine is at state: 'stateA'. Test function call result is: '100'
2) State machine is at SAME state: 'stateA'. Test function call result: '200'
3) State machine is at state: 'stateC'. Test function call result: 'rab oof'
=*= Check property value after restore: $foo='bar' =*=
4) State machine is at state 'stateD'. Test function call result: '2'
5) State machine is at state 'stateB'. Test function call result: '4'