10

Does anybody know a finite state machine that has guard feature in PHP ?

Bamdad Dashtban
  • 354
  • 3
  • 17

4 Answers4

5

Using PEAR's FSM (usage example), you can use the action callback to return the next state if the guard fails, like so:

$payload = '';
$fsm = new FSM('STATE1', $payload);
function guard1($symbol, $payload) {
    if ($payload == 'something') {
        // Guard success, allow transition
        return;
    }
    else {
        // Guard fail, return to previous state
        return 'STATE1';
    }
}
$fsm->addTransition('SYMBOL1', 'STATE1', 'STATE2', 'guard1');

$fsm->process('SYMBOL1');
Rusty Fausak
  • 7,355
  • 1
  • 27
  • 38
1

Look at ezComponents Workflow. Allows you to design workflows with many objects and add in conditionals and states.

user521990
  • 669
  • 1
  • 5
  • 21
1

check out: https://github.com/chriswoodford/techne/tree/v0.2

I think it has the functionality that you're looking for. You define a transition and then can associate a closure that gets called before the transition is processed. here's a simple example:

Define your FSM

  $machine = new StateMachine\FiniteStateMachine();
  $machine->setInitialState('off');

Define the transitions

    $turnOff = new StateMachine\Transition('on', 'off');
    $turnOn = new StateMachine\Transition('off', 'on');

Add a guard to the turnOn transition

    // flipping the switch on requires electricity
    $hasElectricity = true;
    $turnOn->before(function() use ($hasElectricity) {
        return $hasElectricity ? true : false;
    });

Transition from off to on

  $machine->flip();  
  echo $machine->getCurrentState();
  // prints 'on'  

Transition back to off

  $machine->flip();  
  echo $machine->getCurrentState();
  // prints 'off'  

if the $hasElectricity variable had been set to false, the outcome would look like this:

  // oops, forgot to pay that electricity bill
  $hasElectricity = false;

  $turnOn->before(function() use ($hasElectricity) {
      return $hasElectricity ? true : false;
  });

Then, if you try to transition from Off -> On

  $machine->flip();  
  echo $machine->getCurrentState();
  // prints 'off'  

In order to determine where a transition was completed, you'd just have to compare the previous state to the current state.

chriswoodford
  • 1,223
  • 9
  • 8
0

The Conditions in the Metabor Statemachine https://github.com/Metabor/Statemachine can be used as Guards (3rd parameter in Transition constructor). See Example: https://github.com/Metabor/Statemachine-Example/blob/master/Example/Order/Process/Prepayment.php

  • Thanks for your answer, consider to avoid external links since they can broken over time, instead include some relevant code with explaination in your answer – Petter Friberg Nov 26 '15 at 16:18
  • I have given myself an opportunity to implement some state machine with Metabor. The only problem is that without a step by step explanation it is totally difficult to follow what is going on there. Is there any tutorial available out there that I can read? – scruffycoder86 Jun 02 '16 at 11:41
  • The example isn't very clear. The conditions must implement a ConditionInterface which isn't in the same project. However the object requiring the ConditionInterface requires a context variable. https://github.com/Metabor/Statemachine-Example/blob/master/Example/Order/Condition/AuthorizedSuccessful.php Where is this context variable acquired from? How do you set it up for the state machine? – CMCDragonkai Sep 07 '16 at 10:20