PHPackages                             phptry/phptry - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. phptry/phptry

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

phptry/phptry
=============

Try type for PHP

476.2k6[1 issues](https://github.com/asm89/php-try/issues)[3 PRs](https://github.com/asm89/php-try/pulls)PHP

Since May 31Pushed 12y ago4 watchersCompare

[ Source](https://github.com/asm89/php-try)[ Packagist](https://packagist.org/packages/phptry/phptry)[ RSS](/packages/phptry-phptry/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Php Try type
============

[](#php-try-type)

A Try type for PHP.

The Try type is useful when called code will either return a value (Success) or throw an exception (Failure). Instead of relying on the `try {} catch {}`mechanism to handle this cases, the fact that code might either throw or return a value is now encoded in its return type.

The type shows it usefulness with it's ability to create a "pipeline" operations, catching exceptions along the way.

> Note: this implementation of the Try type is called Attempt, because "try" is a reserved keyword in PHP.

Before / after
--------------

[](#before--after)

Before, the `UserService` and `Serializer` code might throw exceptions, so we have an explicit try/catch:

```
try {
    $user = $userService->findBy($id);
    $responseBody = $this->serializeUser($user);

    return new Response($user);
} catch (Exception $ex) {
    return Response('error', 500);
}
```

After, the `UserService` and `Serializer` now return a response of type `Try`meaning that the computation will either be a `Failure` or a `Success`. The combinators on the `Try` type are used to chain the following code in the case the previous operation was successful.

```
return $userService->findBy($id)
    ->flatMap(function($user) { return $this->serializeUser($user); }) // walk the happy path!
    ->map(function($responseBody) { return new Response($responseBody); })
    ->recover(function($ex) { return new Response('error', 500); })
    ->get(); // returns the wrapped value
```

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

[](#installation)

Run:

```
composer require phptry/phptry

```

or add it to your `composer.json` file.

Usage
-----

[](#usage)

> Note: most of the example code below can be tried out with the `user-input.php` example from the `examples/` directory.

### Constructing an Attempt

[](#constructing-an-attempt)

Turn any callable in an `Attempt` using the `Attempt::call()` construct it.

```
\PhpTry\Attempt::call('callableThatMightThrow', array('argument1', 'argument2'));
```

Or use `Success` and `Failure` directly in your API instead of throwing exceptions:

```
function divide($dividend, $divisor) {
    if ($divisor === 0) {
        return new \PhpTry\Failure(new InvalidArgumentException('Divisor cannot be 0.'));
    }

    return new \PhpTry\Success($dividend / $divisor);
}
```

### Using combinators on an Attempt

[](#using-combinators-on-an-attempt)

Now that we have the `Attempt` object we can use it's combinators to handle the success and failure cases.

#### Getting the value

[](#getting-the-value)

Gets the value from Success, or throws the original exception if it was a Failure.

```
$try->get();
```

#### Falling back to a default value if Failure

[](#falling-back-to-a-default-value-if-failure)

Gets the value from Success, or get a provided alternative if the computation failed.

```
// or a provided fallback value
$try->getOrElse(-1);

// or a value returned by the callable
// note: if the provided callable throws, this exception will not be catched
$try->getOrCall(function() { return -1; });

// or else return another Attempt
$try->orElse(Attempt::call('divide', array(42, 21)));

// or else return Another attempt from a callable
$try->orElseCall('promptDivide');
```

#### Walking the happy path

[](#walking-the-happy-path)

Sometimes you care about the Success path and want to propagate or even ignore Failure. The `filter`, `flatMap` and `map` operators shown below will execute the given code if the previous computation was a Success, or propagate the Failure otherwise. If the function passed to `flatMap` or `map` throws, the operation will result in a Failure.

```
// map to Another attempt
$try->flatMap(function($elem) {
    return Attempt::call('divide', array($elem, promptDivide()->get()));
});

// map the success value to another value
$try->map(function($elem) { return $elem * 2; });

// Success, if the predicate holds for the Success value, Failure otherwise
$try->filter(function($elem) { return $elem === 42; })

// only foreachable if success
foreach ($try as $result) {
    echo $result;
}
```

#### Recovering from failure

[](#recovering-from-failure)

When we do care about the Failure path we might want to try and fix things. The `recover` and `recoverWith` operations are for Failure, what `flatMap` and `map` are for Success.

```
// recover with with a value returned by a callable
$try->recover(function($ex) { if ($ex instanceof RuntimeException) { return 21; } throw $ex; })

// recover with with an attempt returned by a callable
$try->recoverWith(function() { return promptDivide(); })
```

The `recover` and `recoverWith` combinators can be useful when calling for example http services that might fail. A failed call can be recovered by calling the service again or calling an alternative service.

#### Don't call us, we'll call you

[](#dont-call-us-well-call-you)

The Try type can also call provided callables on a successful or failed computation:

```
// on* handlers
$try
    ->onSuccess(function($elem) { echo "Result of a / b * c is: $elem\n"; })
    ->onFailure(function($elem) { echo "Something went wrong: " . $elem->getMessage() . "\n"; promptDivide(); })
;
```

#### Lazily executed Attempts

[](#lazily-executed-attempts)

It is possible to execute the provided callable only when needed. This is especially useful when recovering with for example expensive alternatives.

```
$try->orElse(Attempt::lazily('someExpensiveComputationThatMightThrow'));
```

#### Other options

[](#other-options)

When you have [phpoption/phpoption](https://github.com/schmittjoh/php-option) installed, the Attempt can be converted to an Option. In this mapping a Succes maps to Some and a Failure maps to a None value.

```
$try->toOption(); // Some(value) or None()
```

Inspiration
-----------

[](#inspiration)

- Implementation and general idea is based on scala's [Try](http://www.scala-lang.org/api/2.9.3/scala/util/Try.html)
- Schmittjoh's [Option type](https://github.com/schmittjoh/php-option) for PHP

###  Health Score

28

—

LowBetter than 52% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity31

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/78fcc60c1d576c1f19a4c03297931f879354efbb7e054318ffe391a2a2f0a274?d=identicon)[asm89](/maintainers/asm89)

---

Top Contributors

[![asm89](https://avatars.githubusercontent.com/u/657357?v=4)](https://github.com/asm89 "asm89 (10 commits)")

### Embed Badge

![Health badge](/badges/phptry-phptry/health.svg)

```
[![Health](https://phpackages.com/badges/phptry-phptry/health.svg)](https://phpackages.com/packages/phptry-phptry)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
