PHPackages                             phpussd/phpussd - 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. [Framework](/categories/framework)
4. /
5. phpussd/phpussd

ActiveLibrary[Framework](/categories/framework)

phpussd/phpussd
===============

A fast, minimal PHP framework for building state-machine-based USSD applications.

v1.1.0(1mo ago)01MITPHPPHP &gt;=8.1

Since May 30Pushed 1mo agoCompare

[ Source](https://github.com/innochombo/php-ussd-framework)[ Packagist](https://packagist.org/packages/phpussd/phpussd)[ RSS](/packages/phpussd-phpussd/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (4)Used By (0)

PhpUSSD
=======

[](#phpussd)

A fast, minimal PHP framework for building state-machine-based USSD applications.

**PHP 8.1+ · Zero runtime dependencies · 75 tests passing**

---

Features
--------

[](#features)

### Core

[](#core)

FeatureDescription**State machine navigation**Every screen is a menu node. Every input is an explicit transition. No hidden routing — the full application flow is readable from one config file.**Lazy menu instantiation**Only the single menu needed for the current request is constructed. All others are registered by class name and never loaded.**Batched session writes**Session mutations accumulate in memory and flush once at the end of the request. No per-`set()` disk or Redis I/O.**Back / Main / Paginate**`0` (back), `00` (main menu), `99` (next page), and `98` (prev page) are handled by the navigator before `handleInput()` is called. Menus never implement these themselves.**Zero dependencies**The framework `require`s only `php: >=8.1`. Nothing else in Composer. Safe to drop into any PHP environment.### Menu Abstractions

[](#menu-abstractions)

FeatureDescription**`AbstractMenu`**Base class for every screen. Implements `display()`, `handleInput()`, and `getParentMenu()`. Injects session, language, and HTTP client automatically.**`MultiStepMenu` trait**Eliminates manual step-counter boilerplate for multi-input flows. Declare step names; the trait manages position, storage, and advancement — namespaced per class so two flows never overwrite each other.**`PaginatedListMenu`**Base class for lists that exceed one USSD screen. Handles fetch, cache, page boundaries, and `98`/`99` navigation. Subclass implements `fetchItems()`, `itemLabel()`, and `onItemSelected()`.**Guards**Implement `MenuGuardInterface` to protect menus without embedding auth logic inside them. Guards run before both `display()` and `handleInput()`. Multiple guards can be stacked.**Lifecycle hooks**Optional `onEnter()` and `onLeave()` methods on every menu. Use `onEnter()` to pre-fetch data into session; `onLeave()` to clean up.**Error pattern**`errorThen($message, $menuId)` stores an error in session and returns a menu ID. The next `display()` call reads it with `consumeError()` and prepends it to the screen.### Gateway Drivers

[](#gateway-drivers)

DriverFormatWhen to use`AfricasTalkingDriver`Form-encoded POST · plain text `CON …`/`END …`Africa's Talking production gateway`NaloDriver`Form-encoded POST · plain textNalo Solutions gateway`JsonDriver`JSON POST · JSON `{"type","message","sessionId"}`USSD Phone Simulator, REST clients, local devCustomAnyImplement `GatewayDriverInterface`### Session Drivers

[](#session-drivers)

DriverBacking storeWhen to use`FileSessionManager`JSON files on diskDevelopment, low-traffic deployments`RedisSessionManager`Redis (`ext-redis` required)Production, multi-server`ArraySessionManager`In-memory PHP arrayUnit and integration tests### Internationalisation

[](#internationalisation)

FeatureDescription**Multi-language**Register any number of language providers in config. Active language stored in session and restored on every request automatically.**`AbstractLanguage`**Array-backed translation provider. Extend it with a `$translations` array — no config files, no parsing.**Missing key visibility**Missing translation keys render as `[missing:key_name]` rather than empty strings — immediately visible during development.**`sprintf` formatting**`$this->tf('key', $arg1, $arg2)` wraps `sprintf` for parameterised translations.### HTTP Client

[](#http-client)

FeatureDescription**Pre-configured**Injected as `$this->http` in every menu. Base URL, timeout, and default headers set once in config.**Retry with back-off**Retries failed requests using exponential back-off. Retry count is configurable.**Dot-notation responses**`$response->get('user.profile.name')` for nested JSON access without manual array traversal.**Auth helpers**`$this->http->withToken($token)` and `$this->http->withHeaders([...])` for per-request overrides.### Middleware

[](#middleware)

FeatureDescription**Pipeline**Middleware wraps every request. Declared in `app.php`, runs outermost-first. Supports class name, `{class, options}` array, or factory callable.**`CorsMiddleware`**Built-in. Sends `Access-Control-Allow-*` headers and short-circuits `OPTIONS` preflights. Fully configurable per-origin allowlist, methods, headers, credentials, and `max_age`.**Custom middleware**Implement `MiddlewareInterface` — one method: `process(array $payload, callable $next): string`. Call `$next($payload)` to pass through or return directly to short-circuit.### Simulator Integration

[](#simulator-integration)

FeatureDescription**`JsonDriver`**Speaks the same protocol as the [USSD Phone Simulator](https://ussd-phone-simulator.vercel.app/) — accepts `{"sessionId","serviceCode","msisdn","input"}`, returns `{"type","message","sessionId"}`.**JSON body parsing**`index.php` detects `Content-Type: application/json` and reads from `php://input` automatically. No changes to menus needed.**CORS via middleware**Configure `CorsMiddleware` in `app.php` to allow the simulator origin. No CORS logic needed in `index.php`.---

Installation
------------

[](#installation)

```
composer require phpussd/phpussd
```

---

Quick Start
-----------

[](#quick-start)

### 1. `index.php`

[](#1-indexphp)

```
