定制 hbliang/finite-state-machine 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

hbliang/finite-state-machine

Composer 安装命令:

composer require hbliang/finite-state-machine

包简介

A Simple PHP Finite State Machine

README 文档

README

build-status

Features

  • Integration with Laravel

Requirements

  • PHP >= 7.0

Code Examples

A simple state flow chart in a order:

Order: pay process ship created ------> paid ----------> done ----------> shipped | | | cancel | |______ ______| ↓ cancelled 
<?php require_once 'vendor/autoload.php'; $states = ['created', 'paid', 'done', 'shipped', 'cancelled']; $transitions = [ [ 'name' => 'pay', 'from' => ['created'], 'to' => 'paid', ], [ 'name' => 'process', 'from' => ['paid'], 'to' => 'done', ], [ 'name' => 'ship', 'from' => ['done'], 'to' => 'shipped', ], [ 'name' => 'cancel', 'from' => ['created', 'paid'], 'to' => 'cancelled', 'listeners' => [ 'after' => function (\Hbliang\FiniteStateMachine\Event\TransitionEvent $event) { // Email to customer } ] ] ]; class Model { public $state; public function save() { // save to db } } $model = new Model(); $model->state = 'created'; $stateMachine = new \Hbliang\FiniteStateMachine\StateMachine( $model, new \Symfony\Component\EventDispatcher\EventDispatcher(), function (Model $model, \Hbliang\FiniteStateMachine\Contracts\StateInterface $state) { // update your state inside your object after transition. $model->state = $state->getName(); } ); foreach ($states as $state) { $stateMachine->addState(new \Hbliang\FiniteStateMachine\State($state)); } foreach ($transitions as $transition) { $stateMachine->addTransition(new \Hbliang\FiniteStateMachine\Transition( $transition['name'], $transition['from'], $transition['to'], $transition['listener'] ?? [] )); } $stateMachine->initialize($model->state); echo 'current state: ' . $model->state . PHP_EOL; echo 'apply pay' . PHP_EOL; $stateMachine->apply('pay'); echo 'current state: ' . $model->state . PHP_EOL; echo 'Can apply cancel? ' . ($stateMachine->can('cancel') ? 'yes' : 'no') . PHP_EOL; echo 'apply cancel' . PHP_EOL; $stateMachine->apply('cancel'); echo 'current state: ' . $model->state . PHP_EOL;

In Laravel, it is assumed that Model Order have state property. Let make Order integrated with StateMachine. First, Order have to implement Hbliang\FiniteStateMachine\Laravel\StatefulInterface and use Hbliang\FiniteStateMachine\Laravel trait. Then, you can apply transition by method like $order->transition('transition') and check whether can make a transition by method like $order->canTransition('transition') Look at example Order.php below:

<?php namespace App; use Hbliang\FiniteStateMachine\Contracts\TransitionListenerInterface; use Hbliang\FiniteStateMachine\Event\TransitionEvent; use Hbliang\FiniteStateMachine\Laravel\Stateful; use Hbliang\FiniteStateMachine\Laravel\StatefulInterface; use Hbliang\FiniteStateMachine\Contracts\StateInterface; use Illuminate\Database\Eloquent\Model; class Order extends Model implements StatefulInterface { use Stateful; protected $fillable = ['state']; /**  * The state of which you don't declare type explicitly will be seen as normal state.  * If there is not explicitly declared initial state,   * state machine will take the first state of list as initial state.  *   * @return array  */ public function getStates() { return [ 'created' => StateInterface::TYPE_INITIAL, 'paid', 'done', 'cancelled' => StateInterface::TYPE_FINAL, 'shipped', ]; /**  return [  'created', // initial state set by state machine automatically   'paid',  'done',  'cancelled' => StateInterface::TYPE_FINAL,  'shipped',  ];  */ } /**  * @return array  */ public function getTransitions() { return [ 'pay' => [ 'from' => ['created'], 'to' => 'paid', ], 'process' => [ 'from' => ['paid'], 'to' => 'done', 'listeners' => [ 'after' => function (TransitionEvent $event) { // Email to customer } ] ], 'ship' => [ 'from' => ['done'], 'to' => 'shipped', ], 'cancel' => [ 'from' => ['created', 'paid'], 'to' => 'cancelled', 'listeners' => [ 'after' => CancelledListener::class ], ] ]; } /**  * Get state property name in database  *  * @return string  */ public function getStatePropertyName() { return 'state'; } } class CancelledListener implements TransitionListenerInterface {  public function handle() { echo 'Cancelled' . PHP_EOL; } }

It is easy to transition. Like

$order = new App\Order; // if you don't check whether you can transition, it is likely to throw a exception when you actually can't transition.  if ($order->canTransition('cancel')) { $order->transition('cancel'); } $order->save();
  • Don't directly set state property like $order->state = 'cancelled'. It is a extremely dangerous. The only way you can update state is to use method transition();
  • Don't forget to set default state in database. For example in migration, $table->string('state', 20)->default('created');

统计信息

  • 总下载量: 15.63k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: Unknown
  • 更新时间: 2026-01-04

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固