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

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

djsharman/state
===============

The State design pattern. Implemented in PHP and with style.

v1.0(10y ago)51361PHPPHP &gt;=5.3.0

Since Oct 30Pushed 7y ago2 watchersCompare

[ Source](https://github.com/djsharman/state)[ Packagist](https://packagist.org/packages/djsharman/state)[ RSS](/packages/djsharman-state/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (5)Versions (2)Used By (0)

Changes added by Darren Sharman
===============================

[](#changes-added-by-darren-sharman)

This is a State machine generator based on the work of Sebastian Bergmann (thank you Sebastian).

The intent of the [State](http://c2.com/cgi/wiki?StatePattern) design pattern is to "allow an object to alter its behavior when its internal state changes. The object will appear to change its class". The State pattern can be used, for instance, to implement a [Finite State Machine](https://en.wikipedia.org/wiki/Finite-state_machine)efficiently and elegantly. This approach can be useful when implementing business processes or workflows.

This version differs from the original in the following ways:

- You can regenerate your state machines whenever you like without losing your code (See below for how to do this).
- You can now generate multiple state machines at once by using different .xml files. You can configure the output directory in the configuration files.
- It favours convention over configuration so some of the configuration file options have been removed.
- The generated classes are now namespaced so you can use your PSR autoloaders.
- The state classes it generates have two additional methods onEnterState and onExitState. These are called automatically when the state machine enters or leaves a state. I'm guessing you worked that out for yourself though ;-)
- The state machine passes a pointer to the main state machine instance along to each state as the state is instantiated. This means a state can modify the state machines state. $this-&gt;SM-&gt;{operation function name}(); e.g. $this-&gt;SM-&gt;close() from the Door example.
- The visualizer now bases its output on the configuration file for the state machine rather than trying to generate this from the code.
- The visualizer now tags the state transistion arrows with the name of the state change operation.
- The tests that are generated might be broken, I haven’t got around to testing them yet.
- Examples Updated - In the examples folder you will find the Door example from Sebastian generated with the new code. There is also a bigger real world example of a state machine I created using this code to to with handling phone calls. The real code has been removed here, but the main structure of the statemachine is there for you to take a look at. You can see how crazy the diagrams generated can get when the statemachines get bigger.

Making sure your code doesn’t get overwritten
---------------------------------------------

[](#making-sure-your-code-doesnt-get-overwritten)

When you modify one of the functions generated by the generator be sure to move the code between the

```
//###START_CUSTOMCODE2
```

and

```
//###END_CUSTOMCODE2
```

comments. For an example please see onEnterState ([source](examples/statemachines/PwrCall/StartUpState.php)) function in the StartUpState.php file in the PwrCall example folder.

Implementing the generator to work with your existing code
----------------------------------------------------------

[](#implementing-the-generator-to-work-with-your-existing-code)

You need to create one or more XML file to represent your state machine(s). The full XML state machine configuration is covered below. Importantly you should set the target directory *targetdir* where the statemachines are to be generated. This is a path relative to where you run the generator from. Also you should set the *namespace* that the statemachine classes will use.

```

```

You should then create a shell script (or batch file) to call the generator and, optionally, the visualizer.

```
php "..\generator\run.php" _defs
php "..\generator\runViz.php" _defs

```

The generator and visualiser take a single parameter which is the directory containing the state machine XML definition(s).

Example: Door
-------------

[](#example-door)

Consider a class `Door` that represents a door. A door can be in one of three states: open, closed, locked. When a `Door` object receives messages (such as `open()`, `close()`, `lock()`, or `unlock()`) from other objects, it responds differently depending on its current state. For example, the effect of an `open()` message depends on whether the door is in its closed state or not (a locked door has to be unlocked before it can be opened, for instance). The State pattern describes how a `Door` object can exhibit different behavior in each state. The key idea in this pattern is to introduce classes to represent the states of the door.

### DoorState

[](#doorstate)

The `DoorState` interface ([source](examples/statemachines/Door/DoorState.php)) declares an interface common to all classes that represent different states.

```

```

Some parts of the state machine configuration are assumed by convention.

- The name of the statemachine is taken from the name of the XML configuration file
- State tests are always the a given state name prefixed by "is". e.g. the test for OpenDoorState will be isOpenDoorState();
- Operation names in tests are always prefixed "testCan" or "testCannot". e.g. for the OpenDoorTest testCannotOpen and testCanClose.

Visualizing the State Machine
-----------------------------

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

A graphical visualization of the statemachine states and its transitions can be generated based on the state machine's XML specification.

The `runViz.php` ([source](generator/runViz.php)) generates representation of the state machine as a directed graph in [Dot](http://graphviz.org) markup.

[![Visualization of the Door state machine](examples/_defs/diagrams/_djsharman_examples_statemachinesDoor.png)](examples/_defs/diagrams/_djsharman_examples_statemachinesDoor.png)

Documenting the State Machine through Tests
-------------------------------------------

[](#documenting-the-state-machine-through-tests)

Using PHPUnit's [TestDox](http://phpunit.de/manual/current/en/other-uses-for-tests.html#other-uses-for-tests.agile-documentation)functionality we can automatically generate documentation for the state machine based on its tests:

```
OpenDoor
 [x] Can be closed
 [x] Cannot be opened
 [x] Cannot be locked
 [x] Cannot be unlocked

ClosedDoor
 [x] Cannot be closed
 [x] Can be opened
 [x] Can be locked
 [x] Cannot be unlocked

LockedDoor
 [x] Cannot be closed
 [x] Cannot be opened
 [x] Cannot be locked
 [x] Can be unlocked

```

This automatically generated checklist makes it clear which transitions are allowed between the three states of the state machine.

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 67.4% 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

Unknown

Total

1

Last Release

3852d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/87b17048accbb5c98a53ac2ef6baca6bc226eca937a4ca7d2056f35558d16384?d=identicon)[djsharman](/maintainers/djsharman)

---

Top Contributors

[![sebastianbergmann](https://avatars.githubusercontent.com/u/25218?v=4)](https://github.com/sebastianbergmann "sebastianbergmann (29 commits)")[![djsharman](https://avatars.githubusercontent.com/u/5472179?v=4)](https://github.com/djsharman "djsharman (14 commits)")

### Embed Badge

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

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

###  Alternatives

[ramsey/devtools

A Composer plugin to aid PHP library and application development.

7134.7k26](/packages/ramsey-devtools)[jimbojsb/workman

PHP process forking &amp; daemonizing library

608.8k](/packages/jimbojsb-workman)

PHPackages © 2026

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