Download the PHP package llbbl/enum-state-machine without Composer
On this page you can find all versions of the php package llbbl/enum-state-machine. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download llbbl/enum-state-machine
More information about llbbl/enum-state-machine
Files in llbbl/enum-state-machine
Package enum-state-machine
Short Description Zero-configuration, framework-agnostic PHP state machine driven by Enums and Attributes.
License MIT
Homepage https://github.com/llbbl/esm
Informations about the package enum-state-machine
enum-state-machine
Zero-configuration, framework-agnostic PHP state machine driven by Enums and Attributes.
Instead of bloated configuration arrays, you declare transitions, guards, and side-effects directly on the enum that represents your state — so the enum is the documentation, fully typed and statically analyzable.
Core principles
- The enum is the truth — transitions, guards, and side-effects live on the enum case.
- Strictly typed — full IDE autocompletion and PHPStan/Psalm support.
- Agnostic — vanilla PHP, Laravel, Symfony, anything. Optional PSR-11 container (DI for guards/hooks) and PSR-14 dispatcher (transition events); neither is required.
Requirements
- PHP >= 8.1 (Enums + Attributes)
- Optional:
psr/container(resolve guards/hooks via DI),psr/event-dispatcher(emit transition events)
Installation
Concepts
| Piece | Role |
|---|---|
#[Transition(to, guard, before, after, includeSelf)] |
Declares an allowed transition. On a case = from that state; on the enum class = wildcard from any state. Repeatable. |
#[StateMachineConfig(dispatchEvents, event)] |
Class-level config (event dispatching toggle / custom event). |
GuardInterface |
__invoke($from, $to, $context): bool — vetoes a transition. Must be side-effect-free (also run by can()). |
StateHookInterface |
__invoke($from, $to, $context): void — before/after side-effects. |
StateTransitioned |
PSR-14 event emitted after a successful transition. |
StateMachine |
The engine: can(), transitionTo(), getCurrentState(). |
Order of a transition: guards → before hooks → state changes → after hooks → event. Guards/before-hook failures propagate raw and leave state unchanged; an after-hook failure leaves the state changed but throws HookExecutionException.
Development setup
This repo uses mise to pin PHP and just as the task runner.
1. Bootstrap the toolchain (macOS, one-time)
The PHP toolchain recipes live in a php module (just php <recipe>):
| Recipe | Purpose |
|---|---|
just php setup |
One-time bootstrap (Homebrew libs + build the pinned PHP). |
just php version |
Print the active PHP version. |
just php latest |
Latest stable (non-RC) PHP vs the current pin. |
just php floor |
Oldest php.net active-support PHP — the compatibility floor. |
just php bump [VERSION] |
Repin mise.toml to the latest stable (or an explicit version); refuses RCs. |
just php setup compiles PHP from source via mise. Two macOS gotchas it handles for you:
- openssl — the mise php plugin hardcodes the EOL
[email protected], which yields a PHP with no working TLS wrapper (Composer-over-https breaks). The recipe points the build atopenssl@3viabrew --prefix. - link libs — it installs
gd,icu4c,libzip,oniguruma,libxml2(the libs the build force-links) so./configuredoesn't abort. The state machine uses none of these at runtime; they're build-time link deps of the PHP binary.
If the build stops at a
checking for … noline for a different lib, install the matching Homebrew formula and re-runjust php setup.
2. Everyday commands
All recipes run through the mise-pinned PHP.
3. Testing on older PHP (8.1–8.3)
The library supports PHP >= 8.1, but the dev toolchain doesn't: Pest 3 pulls
in symfony/* v8, which requires PHP >= 8.4.1. So the committed
composer.lock only installs on 8.4+, and GitHub CI runs the full suite on the
currently-supported versions (8.4 and 8.5) with a reproducible
composer install.
Older versions are exercised locally via Docker, where each version resolves its own compatible dependency set:
- 8.2 / 8.3 run the full Pest suite — the container does a
composer update(resolvingsymfonyv7, which Pest 3 also supports) before testing. - 8.1 can't install Pest 3 at all, so it only syntax-checks
src/(php -l) to defend the runtime floor.
The repo is mounted read-only and copied inside the container, so a legacy
run's composer update never rewrites your 8.4-resolved host composer.lock.
Requires Docker (docker compose); the recipes live in the legacy module
(compose.yaml + docker/).
License
MIT