PHP 有限状态机使用说明
php 有限状态机使用说明
$config = array(
'graph' => 'myGraphA', // Name of the current graph - there can be many of them attached to the same object
'property_path' => 'stateA', // Property path of the object actually holding the state
'states' => array(
'checkout',
'pending',
'confirmed',
'cancelled'
),
'transitions' => array(
'create' => array(
'from' => array('checkout'),
'to' => 'pending'
),
'confirm' => array(
'from' => array('checkout', 'pending'),
'to' => 'confirmed'
),
'cancel' => array(
'from' => array('confirmed'),
'to' => 'cancelled'
)
),
'callbacks' => array(
'guard' => array(
'guard-cancel' => array(
'to' => array('cancelled'), // Will be called only for transitions going to this state
'do' => function() { var_dump('guarding to cancelled state'); return false; }
)
),
'before' => array(
'from-checkout' => array(
'from' => array('checkout'), // Will be called only for transitions coming from this state
'do' => function() { var_dump('from checkout transition'); }
)
),
'after' => array(
'on-confirm' => array(
'on' => array('confirm'), // Will be called only on this transition
'do' => function() { var_dump('on confirm transition'); }
),
'to-cancelled' => array(
'to' => array('cancelled'), // Will be called only for transitions going to this state
'do' => function() { var_dump('to cancel transition'); }
),
'cancel-date' => array(
'to' => array('cancelled'),
'do' => array('object', 'setCancelled'),
),
)
)
);
各个属性说明
1'property_path' => 'stateA'
需要在 DomainObject
对象中定义,如:
class DomainObject
{
private $stateA = 'checkout';//初始状态
public function getStateA()
{
return $this->stateA;
}
public function setStateA($state)
{
$this->stateA = $state;
}
}
2 states
定义所有可能的状态
'states' => array(
'checkout',
'pending',
'confirmed',
'cancelled'
),
3 transitions
定义了执行动作后的状态变化
'transitions' => array(
'create' => array(
'from' => array('checkout'),
'to' => 'pending'
),
'confirm' => array(
'from' => array('checkout', 'pending'),
'to' => 'confirmed'
),
'cancel' => array(
'from' => array('confirmed'),
'to' => 'cancelled'
)
),
4 callbacks
定义了什么时候执行相对应的回调
'callbacks' => array(
'guard' => array(
'guard-cancel' => array(
'to' => array('cancelled'), // Will be called only for transitions going to this state
'do' => function() { var_dump('guarding to cancelled state'); return false; }
)
),
'before' => array(
'from-checkout' => array(
'from' => array('checkout'), // Will be called only for transitions coming from this state
'do' => function() { var_dump('from checkout transition'); }
)
),
'after' => array(
'on-confirm' => array(
'on' => array('confirm'), // Will be called only on this transition
'do' => function() { var_dump('on confirm transition'); }
),
'to-cancelled' => array(
'to' => array('cancelled'), // Will be called only for transitions going to this state
'do' => function() { var_dump('to cancel transition'); }
),
'cancel-date' => array(
'to' => array('cancelled'),
'do' => array('object', 'setCancelled'),
),
)
)
下面这个定义了是否可以更改到当前状态,guard-cancel
修饰作用没有实际意义,执行的时候会扫描整个数组,当to
的指向状态是cancelled
时执行do
回调,当回调返回true
的时候可以更改到该状态,类似于中间件
'guard' => array(
'guard-cancel' => array(
'to' => array('cancelled'), // Will be called only for transitions going to this state
'do' => function() { var_dump('guarding to cancelled state'); return false; }
)
),
通过guard
之后会先执行before
,数组的key其修饰作用,执行的时候会循环这个数组,当from
的状态是checkout
会执行do
回调,
'before' => array(
'from-checkout' => array(
'from' => array('checkout'), // Will be called only for transitions coming from this state
'do' => function() { var_dump('from checkout transition'); }
)
),
before
执行完之后,接下来开始扫描after
数组,其key起装饰作用。有两种类型一种是on
do
,另一种是to
do
。on
对应的是transitions
的key值,匹配到此key值就执行do
回调。to
对应的是要转换到的状态,匹配到此状态就执行do
回调
'after' => array(
'on-confirm' => array(
'on' => array('confirm'), // Will be called only on this transition
'do' => function() { var_dump('on confirm transition'); }
),
'to-cancelled' => array(
'to' => array('cancelled'), // Will be called only for transitions going to this state
'do' => function() { var_dump('to cancel transition'); }
),
'cancel-date' => array(
'to' => array('cancelled'),
'do' => array('object', 'setCancelled'),
),
)
do
回调有两种方式一种是回调,另一种是DomainObject
的方法
'do' => array('object', 'setCancelled'),
对应
class DomainObject
{
private $stateA = 'checkout';//初始状态
public function getStateA()
{
return $this->stateA;
}
public function setStateA($state)
{
$this->stateA = $state;
}
public function setConfirmedNow()
{
var_dump('I (the object) am set confirmed at '.date('Y-m-d').'.');
}
}
的setConfirmedNow
方法
有三个事件
const PRE_TRANSITION = 'winzou.state_machine.pre_transition';
const POST_TRANSITION = 'winzou.state_machine.post_transition';
const TEST_TRANSITION = 'winzou.state_machine.test_transition';
定义完图后,设置一个初始状态,例如把订单的checkout状态设置进去DomainObject中,然后操作执行相对应的方法(\$stateMachine->apply('create')),可能执行成功($stateMachine->getState(),设置状态进入订单表),也可能执行不成功(错误处理),
本作品采用《CC 协议》,转载必须注明作者和本文链接
看不懂你想表达的意思
@surest E-commerce 中订单系统的设计这篇文章的作者推荐的状态设计,github 上已有英文说明。阅读源码后,对各个属性进行了详细说明,做个记录
怎么和laravel的模型结合使用,比如order模型有个state字段。
acfun keke acc eg
kakaxi
adsdf
kakaxi
bbqcode