PHP code example of denzyl / box

1. Go to this page and download the library: Download denzyl/box library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

denzyl / box example snippets


/** @template T */
interface Item
{
    /** @return T */
    public function grab(): mixed;
}

/** @template TValue
 *  @param Item<TValue> $bag
 *  @return Result<TValue, Throwable>
 */
public static function put(Item $bag): Result

use Result\Item;
use Result\Box;
use Result\Result;

use App\Model\User;
use App\Exception\NotFoundException;

/**
 * @implements Item<User>
 */
class UserFetcher implements Item
{
    public function __construct(
        private int $id,
        private Database $db,
    ) {}

    /** @return User */
    public function grab(): mixed
    {
        $user = $this->db->findUser($this->id);

        if ($user === null) {
            throw new NotFoundException("User {$this->id} not found");
        }

        return $user;
    }
}

/**
 * @return Result<User, Throwable>
 */
function fetchUser(int $id): Result
{
    return Box::put(new UserFetcher($id, $this->db));
}

// Direct — when you already have the value or error
$ok  = Result::ok("Happy value");            // Result<string, never>
$err = Result::error(new Exception("Sad"));  // Result<never, Exception>

// Try — wrap any callable that might throw
$res = Result::try(fn() => $this->riskyOp());

// When — conditional result without an if/else
$res = Result::when($age >= 18, "Access Granted", new Exception("Too young"));

$message = match ($result->state()) {
    ResultState::Ok    => $result->collect()->name,
    ResultState::Error => "Error: " . $result->exception()->getMessage(),
};

$nickname = fetchUser(123)
    ->map(fn(User $u) => $u->name)
    ->map(fn(string $name) => strtolower($name))
    ->unwrapOr("guest");

$result->match(
    onOk:  fn(User $u) => $u->name,
    onErr: fn($e)      => "fallback",
);

$val = $res->collect();                     // throws RuntimeException if Error
$val = $res->unwrapOr("default");           // returns "default" if Error
$val = $res->unwrapOrElse(fn($e) => ...);   // calls closure with the error if Error
$val = $res->expect("User must exist");     // throws with your message if Error

$result
    ->tapOk(fn($v) => Logger::info("Success: $v"))
    ->tapErr(fn($e) => Logger::error("Fail: " . $e->getMessage()));

$active = Result::ok($userList)
    ->filterEach(fn(User $u) => $u->isActive)
    ->mapEach(fn(User $u) => $u->email)
    ->collect();

Result::ok(2)
    ->flatMap(fn(int $n) => match (true) {
        $n > 0 => Result::ok($n * 2),
        default => Result::error(new Exception("Must be positive")),
    });

// recover: turn error back into success with a computed value
$result->recover(fn(Exception $e) => "Fallback for: " . $e->getMessage());
// Result<never, Exception> → Result<string, never>

// orElse: turn error into a new Result (might still be an error)
$result->orElse(fn(Exception $e) => Result::error(new LoggedException($e)));
// Result<T, Exception> → Result<T, LoggedException>

// mapError: transform the error without changing Ok/Error state
$result->mapError(fn(Exception $e) => new DomainException("Wrapper", 0, $e));
// Result<T, Exception> → Result<T, DomainException>

// combine: fail-fast, get all values or first error
$combined = Result::combine([$r1, $r2, $r3]);

// any: first success, or last error if all failed
$any = Result::any([$r1, $r2, $r3]);

// partition: split into successes and failures
$partitioned = Result::partition([$r1, $r2, $r3]);

$tuple = $r1->zip($r2);      // Result<[A, B], E> — pair two results
$res   = $r1->and($r2);      // $r2 if Ok, else $r1 — sequential dependency
$res   = $r1->or($r2);       // $r1 if Ok, else $r2 — fallback

// JSON — useful for API responses
json_encode(Result::ok("hi"));            // {"state":"ok","value":"hi"}
json_encode(Result::error(new Exception("e")));  // {"state":"error","value":"e"}

// Iteration — treat Result as a collection of 0 or 1 items
foreach ($result as $value) { echo $value; }

// Debug — quick string representation
echo (string) $result;                     // Result::Ok('hi')

Item<T>  ──>  Box::put(Item<T>)  ──>  Result<T, Throwable>