PHPackages                             xiaobudongzhang/state-machine - 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. xiaobudongzhang/state-machine

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

xiaobudongzhang/state-machine
=============================

A very lightweight yet powerful PHP state machine

v0.4.2(6y ago)04911MITPHPPHP ^7.1.3

Since May 26Pushed 6y agoCompare

[ Source](https://github.com/xiaobudongzhang/state-machine)[ Packagist](https://packagist.org/packages/xiaobudongzhang/state-machine)[ Docs](https://github.com/xiaobudongzhang/StateMachine)[ RSS](/packages/xiaobudongzhang-state-machine/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (5)Versions (14)Used By (1)

A very lightweight yet powerful PHP state machine
=================================================

[](#a-very-lightweight-yet-powerful-php-state-machine)

Define your states, define your transitions and your callbacks: we do the rest. The era of hard-coded states is over!

[![Build Status](https://camo.githubusercontent.com/7d09d14b92a51933fb0c27dec22e478aa60d6c9aa93b45bbdac84cf2f3280ebe/68747470733a2f2f7472617669732d63692e6f72672f77696e7a6f752f73746174652d6d616368696e652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/winzou/state-machine)

Installation (via composer)
---------------------------

[](#installation-via-composer)

```
{
    "require": {
        "winzou/state-machine": "~0.4"
    }
}
```

Usage
-----

[](#usage)

### Configure a state machine graph

[](#configure-a-state-machine-graph)

In order to use the state machine, you first need to define a graph. A graph is a definition of states, transitions and optionnally callbacks ; all attached on an object from your domain. Multiple graphes can be attached to the same object.

Let's define a graph called *myGraphA* for our `DomainObject` object:

```
$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'),
            ),
        )
    )
);
```

So, in the previous example, the graph has 6 possible states, and those can be achieved by applying some transitions to the object. For example, when creating a new `DomainObject`, you would apply the 'create' transition to the object, and after that the state of it would become *pending*.

### Using the state machine

[](#using-the-state-machine)

#### Definitions

[](#definitions)

The state machine is the object actually manipulating your object. By using the state machine you can test if a transition can be applied, actually apply a transition, retrieve the current state, etc. *A state machine is specific to a couple object + graph.* It means that if you want to manipulate another object, or the same object with another graph, *you need another state machine*.

The factory helps you to get the state machine for these couples object + graph. You give an object and a graph name to it, and it will return you the state machine for this couple. If you want to have this factory as a service in your Symfony2 application, please see the [corresponding StateMachineBundle](https://github.com/winzou/StateMachineBundle).

#### Usage

[](#usage-1)

Please refer to the several examples in the `examples` folder.

#### Callbacks

[](#callbacks)

Callbacks are used to guard transitions or execute some code before or after applying transitions.

Guarding callbacks must return a `bool`. If a guard returns `false`, a transition cannot be performed.

##### Credits

[](#credits)

This library has been highly inspired by , but has taken another direction.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 66.7% 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 ~179 days

Recently: every ~314 days

Total

13

Last Release

2217d ago

PHP version history (2 changes)0.1PHP &gt;=5.3.0

0.4.0PHP ^7.1.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/bef2a2ef65b646eed27d5bef5a7a1133cbff7fc5c54fb5055df4e1ab9042237b?d=identicon)[xiaobudongzhang](/maintainers/xiaobudongzhang)

---

Top Contributors

[![winzou](https://avatars.githubusercontent.com/u/702928?v=4)](https://github.com/winzou "winzou (28 commits)")[![sebdesign](https://avatars.githubusercontent.com/u/667144?v=4)](https://github.com/sebdesign "sebdesign (4 commits)")[![bpolaszek](https://avatars.githubusercontent.com/u/5569077?v=4)](https://github.com/bpolaszek "bpolaszek (1 commits)")[![cawolf](https://avatars.githubusercontent.com/u/1932623?v=4)](https://github.com/cawolf "cawolf (1 commits)")[![cordoval](https://avatars.githubusercontent.com/u/328359?v=4)](https://github.com/cordoval "cordoval (1 commits)")[![dantleech](https://avatars.githubusercontent.com/u/530801?v=4)](https://github.com/dantleech "dantleech (1 commits)")[![bendavies](https://avatars.githubusercontent.com/u/625392?v=4)](https://github.com/bendavies "bendavies (1 commits)")[![patrick-mcdougle](https://avatars.githubusercontent.com/u/1392496?v=4)](https://github.com/patrick-mcdougle "patrick-mcdougle (1 commits)")[![Richtermeister](https://avatars.githubusercontent.com/u/624921?v=4)](https://github.com/Richtermeister "Richtermeister (1 commits)")[![snoob](https://avatars.githubusercontent.com/u/1806237?v=4)](https://github.com/snoob "snoob (1 commits)")[![jgiacobbi](https://avatars.githubusercontent.com/u/2099012?v=4)](https://github.com/jgiacobbi "jgiacobbi (1 commits)")[![blazarecki](https://avatars.githubusercontent.com/u/1443312?v=4)](https://github.com/blazarecki "blazarecki (1 commits)")

---

Tags

eventstatestatemachinecallback

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/xiaobudongzhang-state-machine/health.svg)

```
[![Health](https://phpackages.com/badges/xiaobudongzhang-state-machine/health.svg)](https://phpackages.com/packages/xiaobudongzhang-state-machine)
```

###  Alternatives

[winzou/state-machine

A very lightweight yet powerful PHP state machine

52113.7M18](/packages/winzou-state-machine)[symfony/workflow

Provides tools for managing a workflow or finite state machine

62842.3M170](/packages/symfony-workflow)[sebdesign/laravel-state-machine

Winzou State Machine service provider for Laravel

3401.3M1](/packages/sebdesign-laravel-state-machine)[yohang/finite

A simple PHP Finite State Machine

1.3k3.5M10](/packages/yohang-finite)[iben12/laravel-statable

Statable trait for Laravel Eloquent models

96299.8k1](/packages/iben12-laravel-statable)[gomachan46/state-machine

simple state machine with annotations for PHP, inspired by AASM known as a Ruby state machine.

1893.9k](/packages/gomachan46-state-machine)

PHPackages © 2026

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