graham-campbell/result-type
Lightweight PHP Result type implementation for explicit success/failure returns. Provides Ok/Err-style results to avoid exceptions and clarify control flow. Compatible with PHP 7.2.5–8.5; install via Composer.
Install the package via Composer: composer require graham-campbell/result-type. Begin by importing the core types: use GrahamCampbell\ResultType\Result; use GrahamCampbell\ResultType\Ok; use GrahamCampbell\ResultType\Err;. A first practical use case is wrapping fallible operations where exceptions feel too heavy—e.g., validating DTOs, parsing external data, or handling HTTP client responses—returning Result<mixed, string> to make success/failure explicit.
// Wrap a potentially failing operation
$validated = Result::tryFrom(
fn() => $this->validateEmail($input),
'Invalid email format'
);
Check the README and run composer test on the source to see minimal, self-contained examples.
Use Result at boundaries—not deep inside business logic—to explicit error handling without disrupting Laravel’s exception-driven core. Common patterns:
Result<ValidatedData, string[]> from form/DTO validators instead of throwing exceptions or returning null.then() (monadic bind) to short-circuit on errors:
Result::tryFrom(fn() => $this->fetchRemoteData($id))
->then(fn($data) => Result::tryFrom(fn() => $this->parseData($data), 'Parse failed')))
->mapOk(fn($parsed) => $this->saveToDb($parsed));
Result to responses early:
$result = $service->processOrder($request);
return $result->match(
fn($order) => response()->json($order),
fn($error) => response()->json(['error' => $error], 400)
);
valueOr() for defaults or mapErr() to coerce domain errors into user-friendly messages.Prefer match() over isErr()/value() for exhaustive pattern-matching—ensures both branches are handled.
Ok/Err using match() or check via isOk()/isErr() before calling value()/error(). Unhandled Err causes runtime failures if unwrapped carelessly.Result shines for external interactions (APIs, files, networks), not pure PHP logic (e.g., arithmetic). Excessive wrapping increases cognitive load with little benefit.@return Result<int, string>), as Ok|Err type-hinting requires PHP 8+.new Ok(1) === new Ok(1) is false. Compare inner values via $result->value() when testing equality.Result within service layers, then convert to exceptions or HTTP responses at the edge—avoid mixing styles in the same call stack.tap() to inspect values mid-chain without disrupting flow:
$result->tap(fn($v) => logger()->debug('Processing value', ['v' => $v]))
->mapOk(...);
Result::tryFrom()—test Result consumers by asserting against Ok/Err branches, not exceptions.How can I help you explore Laravel packages today?