PHPackages                             arcturial/fsm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. arcturial/fsm

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

arcturial/fsm
=============

Simple Finite State Machine

48.7k21PHP

Since Jun 10Pushed 11y ago1 watchersCompare

[ Source](https://github.com/arcturial/fsm)[ Packagist](https://packagist.org/packages/arcturial/fsm)[ RSS](/packages/arcturial-fsm/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (1)Used By (1)

Finite State Machine
====================

[](#finite-state-machine)

Master: [![Build Status](https://camo.githubusercontent.com/36630c76995fc35a5e46086341d1fdf873204fed0bc60908e223b8cab75a4b7a/68747470733a2f2f7365637572652e7472617669732d63692e6f72672f61726374757269616c2f66736d2e706e673f6272616e63683d6d6173746572)](http://travis-ci.org/arcturial/fsm)

THis library provides a simple integrated Finite State Machine. The state machine consts of States/Transitions/Triggers.

1. States

---

States define the...states that your machine can be in at any given point during the process. States are connected by transitions.

```
$stateCreated = new State('created', StateInterface::TYPE_INITIAL);
$stateImported = new State('imported');
$stateLive = new State('imported', StateInterface::TYPE_FINAL);
```

State types include `TYPE_INITIAL`, `TYPE_INTERMEDIATE`, `TYPE_FINAL`.

### Actions

[](#actions)

States can contain actions. Actions are set tasks that need to be performed in order to successfully transition. Like saying, "when a payment goes into a pending state, we need to notify a support consultant.".

```
$stateImported = new State('imported');
$stateImported->addAction(new NotifyAction());
$stateImported->addAction(new TwitterAction());
```

2. Transitions

---

Transitions are logical links (paths) between different states. Transitions can also have a transfer condition. Transfer conditions need to evaluate to `true` to transition to a new state. Transitions are constructed by specifying it's initial state and the state to which it needs to transfer.

```
$transitionCreatedImported = new Transition($stateCreated, $stateImported);
$transitionImportedLive = new Transition($stateImported, $stateLive);
```

### Conditions

[](#conditions)

A transition can have an optional condition. This condition must evaluate to true. Conditions can easily be recycled by different states.

```
class ImportPermissions implements \FSM\StateMachine\Condition\ConditionInterface
{
    public function check()
    {
        return true; // Return true/false depending on the outcome of your condition
    }
}

$transitionCreatedImported = new Transition($stateCreated, $stateImported);
$transitionCreatedImported->addCondition(new ImportPermissions());

$transitionImportedLive = new Transition($stateImported, $stateLive);
```

3. Triggers

---

Triggers are certain events that can be fired that will attempt to push the StateMachine forward. Triggers can be associated with a series of different transitions and will automatically determine which transition path to follow.

```
$stateMachine->addTrigger('triggerName', array($transitionCreatedImported, $transitionImportedLive));
```

4. Usage Example

---

Putting it all together, the state machine will look something like this:

```
// Set up a condition
class ImportPermissions implements \FSM\StateMachine\Condition\ConditionInterface
{
    public function check()
    {
        return true; // Return true/false depending on the outcome of your condition
    }
}

// Set up a machine
class ImportMachine extends \FSM\StateMachine\StateMachine
{
    public function __construct($name)
    {
        // Potentially inject some custom dependencies?
        parent::__construct($name);
    }

    protected function configureMachine()
    {
        $stateCreated = new State('created', StateInterface::TYPE_INITIAL);
        $stateImported = new State('imported');
        $stateLive = new State('imported', StateInterface::TYPE_FINAL);

        $transitionCreatedImported = new Transition($stateCreated, $stateImported);
        $transitionCreatedImported->addCondition(new ImportPermissions());

        $transitionImportedLive = new Transition($stateImported, $stateLive);

        // Add the supported machine transitions
        $this->addTransition($transitionCreatedImported);
        $this->addTransition($transitionImportedLive);

        // Add machine triggers
        $this->addTrigger('import', array($transitionCreatedImported, $transitionImportedLive));
        $this->addTrigger('live', array($transitionImportedLive));

        // The initial state can be determined by external dependencies
        // if required
        $this->setCurrentState('created');
    }
}

$machine = new ImportMachine();

echo $machine->getCurrentState(); // echo 'created'

// Trigger machine import
$machine->trigger('import');

echo $machine->getCurrentState(); // echo 'imported' (update the ImportPermissions return to false will echo 'created')

// Trigger machine 'mark as live'
$machine->trigger('live');

echo $machine->getCurrentState(); // echo 'live'
```

Since the "import" trigger contains both the `import` and `live` transition. This trigger can be "deep resolved". This means that it can go straight from importing to making it live. To enable deep resolution you can pass `$machine->trigger('import', true);`

5. More Examples

---

For a more in depth example and a visual representation of a state graph. You can view tests/FSM/StateMachine/Stage/Graph.php in your browser. You need to optionally download the [GraphViz](http://www.graphviz.org/) library in order to generate a more detailed image.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/2787ddd57df0bac305f65f81eba968048955c85863745eaeb3a63c457edcb133?d=identicon)[arcturial](/maintainers/arcturial)

---

Top Contributors

[![arcturial](https://avatars.githubusercontent.com/u/1466729?v=4)](https://github.com/arcturial "arcturial (17 commits)")

### Embed Badge

![Health badge](/badges/arcturial-fsm/health.svg)

```
[![Health](https://phpackages.com/badges/arcturial-fsm/health.svg)](https://phpackages.com/packages/arcturial-fsm)
```

###  Alternatives

[treeware/plant

13355.9k6](/packages/treeware-plant)[aschmelyun/size

Simple PHP helper to convert bytes to different sizes

471.2k](/packages/aschmelyun-size)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
