ba0918 / result
Rust-inspired Result and Option types for PHP, with immutable design and full type safety
Requires
- php: ^8.3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.82
- infection/infection: ^0.34
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.2
This package is auto-updated.
Last update: 2026-08-15 03:32:43 UTC
README
A PHP implementation of Rust's Result and Option types for robust error handling and null safety.
Features
- Type-safe error handling - express success/failure explicitly instead of using exceptions or null
- Functional programming - declarative code through method chaining
- Rust compatible - 97% specification compliance with the Rust standard library
- High quality - PHPStan Level MAX, 100% test coverage
Table of Contents
Installation
composer require ba0918/result
Quick Start
Result Type - Error Handling
<?php use ba0918\Result\{Ok, Err, Result}; // Division function (handles division by zero as error) function safeDivide(float $a, float $b): Result { if ($b === 0.0) { return Err::of("Cannot divide by zero"); } return Ok::of($a / $b); } // Error handling $result = safeDivide(10, 2); if ($result->isOk()) { echo "Result: " . $result->unwrap(); // Result: 5 } else { echo "Error: " . $result->unwrapErr(); } // More concise with method chaining $output = safeDivide(10, 2) ->map(fn($value) => $value * 2) // Double on success ->unwrapOr(0); // Default to 0 on failure echo $output; // 10
Option Type - Null Safety
<?php use ba0918\Result\{Some, None, Option}; // Safely retrieve value from array function findUser(int $id): Option { $users = [1 => 'Alice', 2 => 'Bob']; if (isset($users[$id])) { return Some::of($users[$id]); } return None::instance(); } // Null-safe processing $user = findUser(1) ->map(fn($name) => strtoupper($name)) // Uppercase if found ->unwrapOr('Unknown'); // Default value if not found echo $user; // ALICE
Documentation
Tutorials
- Getting Started Tutorial - understand core concepts in 30 minutes
- Basic Usage - practical patterns and examples
- Advanced Patterns - techniques for experienced developers
Guides
- Best Practices - practical guidelines for your projects
- Debugging Guide - troubleshooting and debugging techniques
- Migration Guide - step-by-step migration from existing code
- Performance Guide - optimization and benchmarks
- IDE Integration - IDE configuration and tooling
References
- Result API Reference - complete Result type method reference
- Option API Reference - complete Option type method reference
- Specification - complete technical specification
- Coding Guidelines - for contributors
Comparisons
- Rust Comparison - mapping to the Rust standard library
- Other Libraries Comparison - technical selection reference
Examples
- Example Collection - copy and paste ready examples
Key Features
Result Type Methods
// Core methods $result->isOk() / $result->isErr() // Success/failure checks $result->map($fn) / $result->mapErr($fn) // Value/error transformation $result->andThen($fn) // Monadic chaining $result->unwrap() / $result->unwrapOr($def) // Value extraction // Shorthand methods $result->isOkAnd($predicate) // Conditional success check $result->mapOr($fn, $default) // Transformation with default
Option Type Methods
// Core methods $option->isSome() / $option->isNone() // Value presence checks $option->map($fn) // Value transformation $option->andThen($fn) // Monadic chaining $option->filter($predicate) // Conditional filtering // Combining operations $option->zip($other) // Combine two Options $option->xor($other) // Exclusive OR
Pipe Operator API (PHP 8.5+)
use function ba0918\Result\Pipe\{andThen, map, mapErr, orElse}; $response = $this->doSomething() |> andThen(fn ($value) => $this->transform($value)) |> orElse(fn ($error) => $this->recover($error)) |> andThen(fn ($value) => $this->respond($value));
The ba0918\Result\Pipe functions are thin adapters over the same-named Result
methods. Each returned closure's input type is bound to the callable's parameter
type (map(fn (int $v) ...) accepts Result<int, E>), so piping a mismatched
Result into a stage is a static error under PHPStan. The pipe operator itself
does not short-circuit — only the business callable passed to each operator is
skipped on Ok/Err. The adapters also work without |> (andThen($op)($result))
on PHP 8.3/8.4.
Requirements
- PHP 8.3+ (the
|>syntax at call sites requires PHP 8.5 or later) - Composer
Development
# Install dependencies composer install # Run tests composer test # Static analysis composer phpstan # Code style check composer cs-check # All quality checks composer check
License
MIT