PHP Classes

How to Use a PHP State Machine Library to Simulate State Machines Using the Package State Machine: Define and processs state machine transitions

Recommend this page to a friend!
     
  Info   Example   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2026-05-04 (8 days ago) RSS 2.0 feedNot yet rated by the usersTotal: Not yet counted Not yet ranked
Version License PHP version Categories
state-machine 1.0MIT/X Consortium ...5Tools
Description 

Author

This package can define and visualize state machines.

It can add the definition of the state machine states and transitions.

The package can also process given state transitions and output the list of transitions that were processed.

Picture of Dwight José Trujillo Barco
  Performance   Level  
Name: Dwight José Trujillo ... <contact>
Classes: 4 packages by
Country: Venezuela Venezuela
Innovation award
Innovation award
Nominee: 2x

Instructions

Example

?<?php

/**
 * Example: Document Processing Pipeline
 *
 * This demonstrates a real-world document processing workflow
 * with validation, OCR processing, and approval
 */

require_once __DIR__ . '/../src/StateMachine.php';

// Helper functions (simuladas)
function log(string $message) { echo "[LOG] $message\n"; }
function
isValidDocument($doc) { return true; }
function
notifyApproval($ctx) { echo "? Document approved!\n"; }
function
dataConfidence($ctx) { return 0.98; }
function
ocrHasError() { return false; }

$pipeline = new StateMachine('received');

$pipeline->addState('received', [
   
'entry' => fn($ctx) => log("Document received: {$ctx['doc']}")
])
->
addState('validating')
->
addState('ocr_processing', [
   
'retryPolicy' => ['max' => 3, 'delay' => 5000]
])
->
addState('extracting_data')
->
addState('approved', [
   
'entry' => fn($ctx) => notifyApproval($ctx)
])
->
addState('rejected')
->
addTransition('received', 'validating')
->
addTransition('validating', 'ocr_processing',
    fn(
$ctx) => isValidDocument($ctx['doc']))
->
addTransition('validating', 'rejected',
    fn(
$ctx) => !isValidDocument($ctx['doc']))
->
addTransition('ocr_processing', 'extracting_data')
->
addTransition('extracting_data', 'approved')
->
addGuard('approved', fn($ctx, $history) =>
   
dataConfidence($ctx) > 0.95);

// Usage with rollback
try {
   
$document = ['id' => 123, 'name' => 'contract.pdf'];
   
   
$pipeline->transition('validating', ['doc' => $document]);
    echo
"Current state: {->exportConfig()['currentState']}\n";
   
   
$pipeline->transition('ocr_processing', ['doc' => $document]);
    echo
"Current state: {->exportConfig()['currentState']}\n";
   
    if (
ocrHasError()) {
       
$pipeline->rollback();
        echo
"Rollback executed!\n";
    }
   
   
$pipeline->transition('extracting_data', ['doc' => $document]);
   
    echo
"\n" . $pipeline->visualizeFlow() . "\n";
   
} catch (
Exception $e) {
    echo
"Error: {$e->getMessage()}\n";
   
$pipeline->rollback();
}


Details

<p align="center"> <img src="https://img.shields.io/badge/PHP-8.0%2B-777BB4?style=for-the-badge&logo=php&logoColor=white"> <img src="https://img.shields.io/badge/License-MIT-green?style=for-the-badge"> <img src="https://img.shields.io/badge/Status-Production%20Ready-brightgreen?style=for-the-badge"> <img src="https://img.shields.io/badge/Dependencies-Zero-blue?style=for-the-badge"> </p>

<h1 align="center">PHP StateMachine</h1>

<p align="center"> <strong>The most advanced declarative state machine engine ever built for PHP.</strong><br> Transactional rollback &bull; Hierarchical states &bull; Visual flow diagrams &bull; Zero dependencies </p>

What Makes This Different

| Capability | This Library | Symfony | Laravel | XState | |---|---|---|---|---| | Transactional Rollback | Yes | No | No | No | | Snapshot Isolation | Yes | No | No | No | | Hierarchical Child Machines | Yes | No | No | Yes | | Guards + Conditions | Yes | No | No | Yes | | Mermaid Visualization | Yes | Graphviz | No | Yes | | Audit History | Yes | No | Yes | Yes | | Retry Policies | Yes | No | No | No | | Zero Dependencies | Yes | No | No | No |

Transactional Rollback

try {
    $pipeline->transition('payment_processing', $context);
    $pipeline->transition('inventory_reservation', $context);
    if ($inventoryUnavailable) {
        $pipeline->rollback();
        $pipeline->rollback();
    }
} catch (Exception $e) {
    while ($pipeline->canRollback()) {
        $pipeline->rollback();
    }
}
Quick Start
Installation
bash
git clone https://github.com/dwight-trujillo/php-state-machine.git
composer require dwight-trujillo/php-state-machine
Basic Usage
php
$workflow = new StateMachine('draft');

$workflow
    ->addState('draft')
    ->addState('review')
    ->addState('published', ['entry' => fn($ctx) => notify($ctx['user'])])
    ->addTransition('draft', 'review')
    ->addTransition('review', 'published')
    ->addGuard('published', fn($ctx) => $ctx['user']->isAdmin());

$workflow->transition('review', ['user' => $currentUser]);
echo $workflow->visualizeFlow();
Core Features
States with Lifecycle Hooks
php
$sm->addState('processing', [
    'entry' => fn($ctx) => startProcess($ctx),
    'exit' => fn($ctx) => cleanup($ctx),
    'timeout' => 300,
    'retryPolicy' => ['max' => 3, 'delay' => 2000]
]);
Guards vs Conditions
php
$sm->addGuard('published', fn($ctx) => $ctx['user']->role === 'admin');
$sm->addTransition('review', 'published', fn($ctx) => qualityCheck($ctx) > 0.95);
Hierarchical Machines
php
$paymentFlow = new StateMachine('idle');
$paymentFlow->addState('charging')->addState('completed');
$paymentFlow->addTransition('idle', 'charging')->addTransition('charging', 'completed');

$orderFlow = new StateMachine('cart');
$orderFlow->addChildState('checkout', $paymentFlow);
Real-World Example: E-Commerce
php
$order = new StateMachine('cart');

$order
    ->addState('cart')
    ->addState('checkout')
    ->addState('paid', ['entry' => fn($ctx) => sendReceipt($ctx['email'])])
    ->addState('shipped')
    ->addState('delivered')
    ->addState('returned')
    ->addState('refunded')
    ->addState('cancelled')
    ->addTransition('cart', 'checkout', fn($ctx) => count($ctx['items']) > 0)
    ->addTransition('checkout', 'paid')
    ->addTransition('paid', 'shipped')
    ->addTransition('shipped', 'delivered')
    ->addTransition('delivered', 'returned')
    ->addTransition('returned', 'refunded')
    ->addTransition('cart', 'cancelled')
    ->addTransition('checkout', 'cancelled')
    ->addGuard('refunded', fn($ctx) => $ctx['user']->isVerified());
Visualization
php
echo $order->visualizeFlow();
Output:

text
graph TD
    cart --> checkout
    checkout --> paid
    checkout --> cancelled
    paid --> shipped
    shipped --> delivered
    delivered --> returned
    returned --> refunded
    cart --> cancelled
    style checkout fill:#f96
API Reference
Method	Description
addState(name, config)	Add state with callbacks and policies
addTransition(from, to, condition)	Define valid transition
addGuard(state, callable)	Protect state entry
addChildState(parent, child)	Attach hierarchical child
transition(to, context)	Execute transition
rollback()	Undo last transition
visualizeFlow()	Generate Mermaid diagram
exportConfig()	Export config and history
License
MIT License - Copyright (c) 2025 Dwight Trujillo

<p align="center"> <strong>Built by <a href="https://github.com/dwight-trujillo">Dwight Trujillo</a></strong> </p> ```

  Files folder image Files (5)  
File Role Description
Files folder imageexamples (2 files)
Files folder imagesrc (1 file)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (5)  /  examples  
File Role Description
  Accessible without login Plain text file document-pipeline.php Example Example script
  Accessible without login Plain text file ecommerce-order.php Example Example script

  Files folder image Files (5)  /  src  
File Role Description
  Plain text file StateMachine.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads  
 100%
Total:0
This week:0