PHPackages                             tmilos/light-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. tmilos/light-fsm

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

tmilos/light-fsm
================

Light and simple finite state machine with nice API for automatic workflow and external state, with export to dot feature

1.0.1(9y ago)12373[1 issues](https://github.com/tmilos/light-fsm/issues)MITPHP

Since Jan 26Pushed 9y ago1 watchersCompare

[ Source](https://github.com/tmilos/light-fsm)[ Packagist](https://packagist.org/packages/tmilos/light-fsm)[ RSS](/packages/tmilos-light-fsm/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

Light FSM
=========

[](#light-fsm)

[![License](https://camo.githubusercontent.com/cd0d0ac4f8e3212cb738301a14551fea97bef166503a4ae362d5d6d4ba96b02f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f746d696c6f732f6c696768742d66736d2e737667)](https://packagist.org/packages/tmilos/light-fsm)[![Build Status](https://camo.githubusercontent.com/7676c6272044b39a5da3f35319fe2a21bc285ecc8af9c026962253e4bed38982/68747470733a2f2f7472617669732d63692e6f72672f746d696c6f732f6c696768742d66736d2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/tmilos/light-fsm)[![Coverage Status](https://camo.githubusercontent.com/0d7603bcf5c301d7f11f092df2ebb84b787e4754ceae4eb62de7b7369296f473/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f746d696c6f732f6c696768742d66736d2f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/tmilos/light-fsm?branch=master)[![HHVM Status](https://camo.githubusercontent.com/d66d451ec986cc5b238e9b0f5382067de9a41ae202b17b730586747018c0ce56/687474703a2f2f6868766d2e683463632e64652f62616467652f746d696c6f732f6c696768742d66736d2e7376673f7374796c653d666c6174)](http://hhvm.h4cc.de/package/tmilos/light-fsm)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/31ab1971a6bd27b295b0aa536e2e6a60dd2d18ef1991d6dd7b385d34e0bd6138/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f746d696c6f732f6c696768742d66736d2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/tmilos/light-fsm/?branch=master)[![SensioLabsInsight](https://camo.githubusercontent.com/5d9710d7d5a7029967df027b8081d77710815d86d71a1cf93faf1f8fca566c35/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f34623666616637392d306236632d343963312d616663352d6330303630393833356361302f736d616c6c2e706e67)](https://insight.sensiolabs.com/projects/4b6faf79-0b6c-49c1-afc5-c00609835ca0)

Finite-state machine FSM PHP library. Create state machines and lightweight state machine-based workflows directly in PHP code.

```
$phoneCall = new StateMachine(State::OFF_HOOK);

$phoneCall->configure(State::OFF_HOOK)
    ->permit(Event::CALL_DIALED, State::RINGING);

$phoneCall->configure(State::RINGING)
    ->permit(Event::HUNG_UP, State::OFF_HOOK)
    ->permit(Event::CALL_CONNECTED, State::CONNECTED);

$phoneCall->configure(State::CONNECTED)
    ->onEntry([$this, 'startTimer'])
    ->onExit([$this, 'stopTimer'])
    ->permit(Event::HUNG_UP, State::OFF_HOOK)
    ->permit(Event::PLACE_ON_HOLD, State::ON_HOLD);

$phoneCall->fire(Event::CALL_DIALED);
$this->assertEquals(State::RINGING, $phoneCall->getCurrentState());
```

This project, as well as the example above, was inspired by [stateless](https://github.com/dotnet-state-machine/stateless).

Features
--------

[](#features)

- State and trigger events of type string or int
- Firing trigger events with additional data
- Hierarchical states
- Entry/exit events for states
- Introspection
- Guard callbacks to support conditional transitions
- Ability to store state externally (for example, in a property tracked by an ORM)
- Export to DOT graph

Firing trigger events with additional data
------------------------------------------

[](#firing-trigger-events-with-additional-data)

Event can be fired with additional data `StateMachine::fire($event, $data)` that will be passed and available to entry/exit and guard listeners, so they can base their logic based on it.

Hierarchical States
-------------------

[](#hierarchical-states)

In the example below, the `ON_HOLD` state is a substate of the `CONNECTED` state. This means that an `ON_HOLD` call is still connected.

```
$phoneCall->configure(State::ON_HOLD)
    ->subStateOf(State::CONNECTED)
    ->permit(Event::CALL_CONNECTED, State::CONNECTED);
```

In addition to the `StateMachine::getCurrentState()` method, which will report the precise current state, an `isInState($state)`method is also provided. `isInState($state)` will take substates into account, so that if the example above was in the `ON_HOLD` state, `isInState(State::CONNECTED)` would also evaluate to `true`.

Entry/Exit Events
-----------------

[](#entryexit-events)

In the example, the `startTimer()` method will be executed when a call is connected. The `stopTimer()` will be executed when call completes.

When call moves between the `CONNECTED` and `ON_HOLD` states, since the `ON_HOLD` state is a substate of the `CONNECTED` state, these listeners can distinguish substates and note that call is still connected based on the first `$isSubState` argument.

External State Storage
----------------------

[](#external-state-storage)

In order to listen for state changes for persistence purposes, for example with some ORM tool, pass the listener callback to the `StateMachine` constructor.

```
$stateObject = $orm-find();

$stateMachine = new StateMachine(
    function () use ($stateObject) {
        return $stateObject->getValue();
    },
    function ($state) use ($stateObject) {
        $stateObject->setValue($state);
        $orm->persist($stateObject);
    }
);
```

In this case, when `StateMachine` is constructed with two callbacks, the state is held totaly external, and each time `StateMachine` needs current state, the first callback will be called, and each time the state changes, the second callback will be called.

Introspection
-------------

[](#introspection)

The state machine can provide a list of the trigger events than can be successfully fired within the current state by the `StateMachine::getPermittedTriggers()` method.

Guard Clauses
-------------

[](#guard-clauses)

The state machine will choose between multiple transitions based on guard clauses, e.g.:

```
$phoneCall->configure(State::OFF_HOOK)
    .permit(Trigger::CALL_DIALLED, State::RINGING, function ($data) { return IsValidNumber($data); })
    .permit(Trigger::CALL_DIALLED, State::BEEPING, function ($data) { return !IsValidNumber($data); });
```

Export to DOT graph
-------------------

[](#export-to-dot-graph)

It can be useful to visualize state machines on runtime. With this approach the code is the authoritative source and state diagrams are by-products which are always up to date.

```
$phoneCall->configure(State::OFF_HOOK)
    .permit(Trigger::CALL_DIALED, State::RINGING, 'IsValidNumber');
$graph = phoneCall->toDotGraph();
```

The `StateMachine::toDotGraph()` method returns a string representation of the state machine in the [DOT graph language](https://en.wikipedia.org/wiki/DOT_(graph_description_language)), e.g.:

```
digraph {
 "off-hook" -> "ringing" [label="call-dialed [IsValidNumber]"];
}

```

This can then be rendered by tools that support the DOT graph language, such as the [dot command line tool](http://www.graphviz.org/doc/info/command.html) from [graphviz.org](http://www.graphviz.org/) or [viz.js](https://github.com/mdaines/viz.js). See () for instant gratification. Command line example to generate a PDF file:

```
> dot -T pdf -o phoneCall.pdf phoneCall.dot
```

###  Health Score

30

—

LowBetter than 62% of packages

Maintenance18

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity64

Established project with proven stability

 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.

###  Release Activity

Cadence

Every ~329 days

Total

2

Last Release

3478d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1e5954d541c3e6ce57f3674bd4ce58bf22629f70b8e8a8779aec754787d26e7e?d=identicon)[tmilos](/maintainers/tmilos)

---

Top Contributors

[![tmilos](https://avatars.githubusercontent.com/u/1818373?v=4)](https://github.com/tmilos "tmilos (20 commits)")

---

Tags

dotworkflowstatemachinefsmfinite-state machinestate-machineexternal stateexport to dot

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[symfony/workflow

Provides tools for managing a workflow or finite state machine

62944.6M239](/packages/symfony-workflow)[yohang/finite

A simple PHP Finite State Machine

1.3k3.6M10](/packages/yohang-finite)[tarfin-labs/event-machine

Event-driven state machines for Laravel with event sourcing, type-safe context, and full audit trail.

199.1k](/packages/tarfin-labs-event-machine)[eftec/statemachineone

A state Machine library for business processes

1144.0k](/packages/eftec-statemachineone)[metabor/statemachine

Statemachine in PHP 8.2+

102150.8k3](/packages/metabor-statemachine)[pwm/s-flow

A lightweight library for defining state machines

742.5k](/packages/pwm-s-flow)

PHPackages © 2026

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