PHPackages                             ifixit/php7-optional - 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. ifixit/php7-optional

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

ifixit/php7-optional
====================

PHP 7 optional wrapper that provides an alternative to null

3.0(3y ago)777.7k↓47.9%2[3 issues](https://github.com/iFixit/php7-optional/issues)MITPHPPHP ^7.2 || ^8.0CI failing

Since Sep 23Pushed 3y ago10 watchersCompare

[ Source](https://github.com/iFixit/php7-optional)[ Packagist](https://packagist.org/packages/ifixit/php7-optional)[ RSS](/packages/ifixit-php7-optional/feed)WikiDiscussions master Synced 3d ago

READMEChangelogDependencies (2)Versions (13)Used By (0)

php7-optional
=============

[](#php7-optional)

[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![Tests](https://github.com/iFixit/php7-optional/actions/workflows/test.yaml/badge.svg?branch=master)](https://github.com/iFixit/php7-optional/actions/workflows/test.yaml)[![Stable Version](https://camo.githubusercontent.com/56aa02778cc9a42044487e289934f24ac9410e1649ec3cd81361ff5a601d2bb2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6966697869742f706870372d6f7074696f6e616c2e737667)](https://packagist.org/packages/ifixit/php7-optional)[![Downloads](https://camo.githubusercontent.com/b4375a59bca26ddf034675a33bd2bd7d7897650fb587c91e3ee767d36dbf1374/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f6966697869742f706870372d6f7074696f6e616c2e737667)](https://packagist.org/packages/ifixit/php7-optional)[![codecov](https://camo.githubusercontent.com/76edf2a4e2517a272a5847d9e4751f023c2542f86f530718340b5a82ffe00498/68747470733a2f2f636f6465636f762e696f2f67682f6946697869742f706870372d6f7074696f6e616c2f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/iFixit/php7-optional)[![psalm](https://camo.githubusercontent.com/1079aca51afdfbe3cb9f984c5624606e710751a2657febb33f6022b37df4bdcc/68747470733a2f2f73686570686572642e6465762f6769746875622f6966697869742f706870372d6f7074696f6e616c2f6c6576656c2e737667)](https://shepherd.dev/github/ifixit/php7-optional)[![psalm](https://camo.githubusercontent.com/4fd7750e3828784f62e6028c0ddf81476d6da12273768246e7663959e024352b/68747470733a2f2f73686570686572642e6465762f6769746875622f6966697869742f706870372d6f7074696f6e616c2f636f7665726167652e737667)](https://shepherd.dev/github/ifixit/php7-optional)[![Pull Requests](https://camo.githubusercontent.com/279d3c276ec5de5a3369b7c1f5c8ccf23b633e1edf47a4378fadfdeb2185b48e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e7376673f6c6f6e6743616368653d74727565)](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?longCache=true)

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

[](#installation)

```
composer require ifixit/php7-optional
```

Usage
-----

[](#usage)

There are 3 main classes:

- [Optional\\Option](https://php7-optional.surge.sh/Optional/Option.html)
    - Conceptually: Some or None. This is a box that optionally holds a value. Use this to replace null.
- [Optional\\Either](https://php7-optional.surge.sh/Optional/Either.html)
    - Conceptually: Left or Right. This is a box that is bi-state. Can be Left, or Right. Not Both, not none. You can apply the same transformations to the left side as you can to the right.
- [Optional\\Result](https://php7-optional.surge.sh/Optional/Result.html)
    - Conceptually: Okay or Error. This is a box that is bi-state, but leans towards okay state. The error state is limited as we want to make this object easy to deal with mapping or dump error.
    - All callables have `Throwable` auto wrapped and thrown at the end of the chain.
- [Optional\\UnsafeResult](https://php7-optional.surge.sh/Optional/UnsafeResult.html)
    - Conceptually: Okay or Error. This is a box that is bi-state, but leans towards okay state. The error state is limited as we want to make this object easy to deal with mapping or dump error.
    - All callables do not have `Throwable` auto wrapped. Thus, an Exception will be thrown immediately.

[Read the full docs](https://php7-optional.surge.sh/)
-----------------------------------------------------

[](#read-the-full-docs)

Using Option
------------

[](#using-option)

To use Optional, simply import the following namespace:

```
use Optional\Option;
```

Creating optional values
------------------------

[](#creating-optional-values)

There are examples under `examples`.

Here is one of them which will show how fluently you can describe the chnage you want to apply.

```
use Optional\Result;

class Curl {
   public static function request(string $url): array {
      return [
         'code' => 200,
         'url' => $url,
         'data' =>
            '{
               "environment_config": {
                 "app": {
                   "name": "Sample App",
                   "url": "http://10.0.0.120:8080/app/"
                 },
                 "database": {
                   "name": "mysql database",
                   "host": "10.0.0.120",
                   "port": 3128,
                   "username": "root",
                   "password": "toor"
                 },
                 "rest_api": "http://10.0.0.120:8080/v2/api/"
               }
             }'
      ];
   }
}

$responseToResult = function (array $response): Result {
   $wasGood = $response['code'] == 200;

   if ($wasGood) {
      return SimpleResult::okay($response);
   } else {
      $url = $response['url'];
      $code = $response['code'];
      return SimpleResult::error("The request to $url failed with code $code!");
   }
};

$response = Curl::request('http:://www.github.com');

$result = $responseToResult($response);

$dbConnectionStr = $result
   ->map(function ($result) {
      return json_decode($result['data'], true);
   })
   ->notFalsy("Json failed to decode!")
   ->map(function(array $json) {
      $dbData = $json['environment_config']['database'];

      $host = $dbData['host'];
      $port = $dbData['port'];
      $username = $dbData['username'];
      $password = $dbData['password'];

      return "Server=$host;Port=$port;Uid=$username;Pwd=$password;";
   })
   ->dataOrThrow();

echo "Connection str: $dbConnectionStr \n";

$dbConnectionResult = $result
   ->map(function ($result) {
      return false;
   })
   ->notFalsy("Json failed to decode!")
   ->map(function(array $json) {
      $dbData = $json['environment_config']['database'];

      $host = $dbData['host'];
      $port = $dbData['port'];
      $username = $dbData['username'];
      $password = $dbData['password'];

      return "Server=$host;Port=$port;Uid=$username;Pwd=$password;";
   });

   try {
      $dbConnectionResult->dataOrThrow();
   } catch (Throwable $ex) {
      // Don't want to kill the example
      echo "Example of a wrapped exception: {$ex->getMessage()}\n";
   }

   $defaultValue = $dbConnectionResult
   ->orSetDataTo('Server=myServerAddress;Port=1234;Database=myDataBase;Uid=myUsername;Pwd=myPassword;')
   ->dataOrThrow();

   echo "Example of setting to a default: $defaultValue\n";
```

Using Either
------------

[](#using-either)

To use Either, simply import the following namespace:

```
use Optional\Either;
```

Using Result
------------

[](#using-result)

To use Result, simply import the following namespace:

```
use Optional\Result;
```

### Result Methods

[](#result-methods)

#### Creation (Boxing)

[](#creation-boxing)

---

- static okay($data): Result
- static error(Throwable $errorData): Result
- static okayWhen($data, Throwable $errorValue, callable $filterFunc): Result
- static errorWhen($data, Throwable $errorValue, callable $filterFunc): Result
- static okayNotNull($data, Throwable $errorValue): Result
- static fromArray(array $array, $key, Throwable $rightValue = null): Result

### Flipping

[](#flipping)

---

- toError($errorValue): Result
- toOkay($dataValue): Result

### Unboxing

[](#unboxing)

---

- dataOrThrow()

### State

[](#state)

---

- isOkay(): bool
- isError(): bool
- contains($value): bool
- errorContains($value): bool
- exists(callable $existsFunc): bool

### Transformation

[](#transformation)

---

- orSetDataTo($data): Result
- orCreateResultWithData(callable $alternativeFactory): Result
- okayOr(self $alternativeResult): Result
- createIfError(callable $alternativeResultFactory): Result
- map(callable $mapFunc): Result
- mapError(callable $mapFunc): Result
- andThen(callable $mapFunc): Result
- flatMap(callable $mapFunc): Result
- toErrorIf(callable $filterFunc, Throwable $errorValue): Result
- toOkayIf(callable $filterFunc, $data): Result
- notNull(Throwable $errorValue): Result
- notFalsy(Throwable $errorValue): Result

### Side Effect

[](#side-effect)

- run(callable $dataFunc, callable $errorFunc)
- runOnOkay(callable $dataFunc): void
- runOnError(callable $errorFunc): void

Licence
=======

[](#licence)

MIT

Special Thanks
==============

[](#special-thanks)

Heavily inspired by . In fact this is essentially a port of this library.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance11

Infrequent updates — may be unmaintained

Popularity36

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 91.2% 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.

###  Release Activity

Cadence

Every ~131 days

Recently: every ~293 days

Total

10

Last Release

1297d ago

Major Versions

1.6.0 → 2.02019-11-25

2.1 → 3.02022-12-16

PHP version history (3 changes)1.0PHP ^7.2

1.2.0PHP ^7.1

2.1PHP ^7.2 || ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/26855?v=4)[Daniel Beardsley](/maintainers/danielbeardsley)[@danielbeardsley](https://github.com/danielbeardsley)

![](https://www.gravatar.com/avatar/ca99660e081ca55522acf43c9b2a68a5fad39ae02c9f204fc11a744a9d708cf2?d=identicon)[jarstelfox](/maintainers/jarstelfox)

---

Top Contributors

[![jarstelfox](https://avatars.githubusercontent.com/u/857362?v=4)](https://github.com/jarstelfox "jarstelfox (186 commits)")[![djmetzle](https://avatars.githubusercontent.com/u/6876047?v=4)](https://github.com/djmetzle "djmetzle (13 commits)")[![sterlinghirsh](https://avatars.githubusercontent.com/u/589425?v=4)](https://github.com/sterlinghirsh "sterlinghirsh (2 commits)")[![andyg0808](https://avatars.githubusercontent.com/u/1283490?v=4)](https://github.com/andyg0808 "andyg0808 (1 commits)")[![davidrans](https://avatars.githubusercontent.com/u/806152?v=4)](https://github.com/davidrans "davidrans (1 commits)")[![ptondereau](https://avatars.githubusercontent.com/u/4287777?v=4)](https://github.com/ptondereau "ptondereau (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ifixit-php7-optional/health.svg)

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

PHPackages © 2026

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