Minimal, type-safe Result type for explicit success/failure handling in PHP (PHP 8.2+).
Composer:
composer require maxiviper117/result-flowWhy Result Flow?
- Explicit branches: handle success with
then()and failures withotherwise()(or both withmatch()). - Metadata travels with the pipeline (correlation IDs, audit context, failed input).
- Exceptions are captured by default but you can opt into
thenUnsafe()for transactional behavior. - Built-in helpers: retries, JSON/XML transformers, and Laravel boundary helpers.
Quick links: Getting Started • API reference
Quick pipeline + match:
use Maxiviper117\\ResultFlow\\Result;
$result = Result::ok(['order_id' => 123, 'total' => 42])
->then(fn($o) => $o['total'] > 0 ? Result::ok($o) : Result::fail('empty'))
->then(fn($o) => Result::ok(['saved' => true, 'id' => $o['order_id']]));
echo $result->match(
onSuccess: fn($v) => json_encode($v),
onFailure: fn($e) => json_encode(['error' => (string) $e]),
);Metadata chaining (attach/propagate context):
Result::ok(['id' => 1], ['request_id' => 'r-1'])
->mergeMeta(['started_at' => microtime(true)])
->then(fn($v, $meta) => Result::ok($v, [...$meta, 'validated' => true]));Exception → Result (wrap a throwing call):
$res = Result::of(fn() => mayThrow())
->otherwise(fn($e) => Result::fail('downstream error'));Laravel boundary (toResponse() returns a Laravel response when available):
$result = Result::ok(['message' => 'ok']);
$response = $result->toResponse(); // Response instance in Laravel, array fallback otherwise- Use in controllers, background jobs, HTTP client adapters, or transactional flows where you want explicit success/failure handling and metadata propagation.
- Use
toDebugArray()to produce a sanitized, debug-friendly shape. Configure sanitization viaconfig/result-flow.phpin Laravel projects. See the hosted docs for debugging and sanitization.
- Use
Result::retry()for simple retry needs orResult::retrier()for advanced configurations (jitter, max attempts, etc.). Read more in the hosted Retrying Operations guide. - When you need to know how many attempts ran, call
->attachAttemptMeta()before->attempt()to merge['retry' => ['attempts' => ...]]into the returned metadata.
- Convert exceptions to
ResultwithResult::of(). Preferthen()for safe chaining andthenUnsafe()when you need exceptions to bubble (e.g., DB transactions).
See CONTRIBUTING.md. Run the test suite with:
composer testMIT — see LICENSE.md.