PHPackages                             phpoption/phpoption - 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. phpoption/phpoption

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

phpoption/phpoption
===================

Option Type for PHP

1.9.5(4mo ago)2.7k541.2M—3.6%67[1 issues](https://github.com/schmittjoh/php-option/issues)[4 PRs](https://github.com/schmittjoh/php-option/pulls)20Apache-2.0PHPPHP ^7.2.5 || ^8.0CI passing

Since Nov 13Pushed 4mo ago26 watchersCompare

[ Source](https://github.com/schmittjoh/php-option)[ Packagist](https://packagist.org/packages/phpoption/phpoption)[ GitHub Sponsors](https://github.com/GrahamCampbell)[ Fund](https://tidelift.com/funding/github/packagist/phpoption/phpoption)[ RSS](/packages/phpoption-phpoption/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (2)Versions (32)Used By (20)

PHP Option Type
===============

[](#php-option-type)

This package implements the Option type for PHP!

[![Banner](https://user-images.githubusercontent.com/2829600/71564011-3077bf00-2a91-11ea-9083-905702cc262b.png)](https://user-images.githubusercontent.com/2829600/71564011-3077bf00-2a91-11ea-9083-905702cc262b.png)

[![Software License](https://camo.githubusercontent.com/f9a2da5664498a2a168a000b85719b4e5a61b6df8aae02cca978ef2580f8b1dc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d417061636865253230322e302d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Total Downloads](https://camo.githubusercontent.com/12a905c7dcfe2c1b3cbe1761eaf4d1a8a6f66e81e977e6835fbf6b641211eb5c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7068706f7074696f6e2f7068706f7074696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/phpoption/phpoption)[![Latest Version](https://camo.githubusercontent.com/bfedef93f4de52f3556b2fc01345192be31eaebf6eddbddd5c1f2d2fe239700a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f7363686d6974746a6f682f7068702d6f7074696f6e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/schmittjoh/php-option/releases)

**Special thanks to [our sponsors](https://github.com/sponsors/GrahamCampbell)**

---

Motivation
----------

[](#motivation)

The Option type is intended for cases where you sometimes might return a value (typically an object), and sometimes you might return a base value (typically null) depending on arguments, or other runtime factors.

Often times, you forget to handle the case where a base value should be returned. Not intentionally of course, but maybe you did not account for all possible states of the system; or maybe you indeed covered all cases, then time goes on, code is refactored, some of these your checks might become invalid, or incomplete. Suddenly, without noticing, the base value case is not handled anymore. As a result, you might sometimes get fatal PHP errors telling you that you called a method on a non-object; users might see blank pages, or worse.

On one hand, the Option type forces a developer to consciously think about both cases (returning a value, or returning a base value). That in itself will already make your code more robust. On the other hand, the Option type also allows the API developer to provide more concise API methods, and empowers the API user in how he consumes these methods.

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

[](#installation)

Installation is super-easy via [Composer](https://getcomposer.org/):

```
$ composer require phpoption/phpoption
```

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

Usage
-----

[](#usage)

### Using the Option Type in your API

[](#using-the-option-type-in-your-api)

```
class MyRepository
{
    public function findSomeEntity($criteria): \PhpOption\Option
    {
        if (null !== $entity = $this->em->find(...)) {
            return new \PhpOption\Some($entity);
        }

        // We use a singleton, for the None case.
        return \PhpOption\None::create();
    }
}
```

If you are consuming an existing library, you can also use a shorter version which by default treats `null` as `None`, and everything else as `Some` case:

```
class MyRepository
{
    public function findSomeEntity($criteria): \PhpOption\Option
    {
        return \PhpOption\Option::fromValue($this->em->find(...));

        // or, if you want to change the none value to false for example:
        return \PhpOption\Option::fromValue($this->em->find(...), false);
    }
}
```

### Case 1: You always Require an Entity in Calling Code

[](#case-1-you-always-require-an-entity-in-calling-code)

```
$entity = $repo->findSomeEntity(...)->get(); // returns entity, or throws exception
```

### Case 2: Fallback to Default Value If Not Available

[](#case-2-fallback-to-default-value-if-not-available)

```
$entity = $repo->findSomeEntity(...)->getOrElse(new Entity());

// Or, if you want to lazily create the entity.
$entity = $repo->findSomeEntity(...)->getOrCall(function() {
    return new Entity();
});
```

More Examples
-------------

[](#more-examples)

### No More Boiler Plate Code

[](#no-more-boiler-plate-code)

```
// Before
$entity = $this->findSomeEntity();
if (null === $entity) {
    throw new NotFoundException();
}
echo $entity->name;

// After
echo $this->findSomeEntity()->get()->name;
```

### No More Control Flow Exceptions

[](#no-more-control-flow-exceptions)

```
// Before
try {
    $entity = $this->findSomeEntity();
} catch (NotFoundException $ex) {
    $entity = new Entity();
}

// After
$entity = $this->findSomeEntity()->getOrElse(new Entity());
```

### More Concise Null Handling

[](#more-concise-null-handling)

```
// Before
$entity = $this->findSomeEntity();
if (null === $entity) {
    return new Entity();
}

return $entity;

// After
return $this->findSomeEntity()->getOrElse(new Entity());
```

### Trying Multiple Alternative Options

[](#trying-multiple-alternative-options)

If you'd like to try multiple alternatives, the `orElse` method allows you to do this very elegantly:

```
return $this->findSomeEntity()
    ->orElse($this->findSomeOtherEntity())
    ->orElse($this->createEntity());
```

The first option which is non-empty will be returned. This is especially useful with lazy-evaluated options, see below.

### Lazy-Evaluated Options

[](#lazy-evaluated-options)

The above example has the flaw that we would need to evaluate all options when the method is called which creates unnecessary overhead if the first option is already non-empty.

Fortunately, we can easily solve this by using the `LazyOption` class:

```
return $this->findSomeEntity()
    ->orElse(new LazyOption(array($this, 'findSomeOtherEntity')))
    ->orElse(new LazyOption(array($this, 'createEntity')));
```

This way, only the options that are necessary will actually be evaluated.

Performance Considerations
--------------------------

[](#performance-considerations)

Of course, performance is important. Attached is a performance benchmark which you can run on a machine of your choosing. The overhead incurred by the Option type comes down to the time that it takes to create one object, our wrapper, and one additional method call to retrieve the value from the wrapper. Unless you plan to call a method thousands of times during a request, there is no reason to stick to the `object|null` return value; better give your code some options!

Security
--------

[](#security)

If you discover a security vulnerability within this package, please send an email to . All security vulnerabilities will be promptly addressed. You may view our full security policy [here](https://github.com/schmittjoh/php-option/security/policy).

License
-------

[](#license)

PHP Option Type is licensed under [Apache License 2.0](LICENSE).

For Enterprise
--------------

[](#for-enterprise)

Available as part of the Tidelift Subscription

The maintainers of `phpoption/phpoption` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpoption-phpoption?utm_source=packagist-phpoption-phpoption&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)

###  Health Score

74

—

ExcellentBetter than 100% of packages

Maintenance74

Regular maintenance activity

Popularity82

Widely adopted with strong download metrics

Community47

Growing community involvement

Maturity79

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~165 days

Recently: every ~259 days

Total

30

Last Release

142d ago

Major Versions

0.9.0 → 1.0.02012-11-18

PHP version history (5 changes)0.9.0PHP &gt;=5.3.0

1.6.0PHP ^5.5.9 || ^7.0

1.7.3PHP ^5.5.9 || ^7.0 || ^8.0

1.8.0PHP ^7.0 || ^8.0

1.9.0PHP ^7.2.5 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/9da34818b48c46c2690876202264d1e45cb9893c368facb55f8851e47495ecfb?d=identicon)[johannes](/maintainers/johannes)

---

Top Contributors

[![GrahamCampbell](https://avatars.githubusercontent.com/u/2829600?v=4)](https://github.com/GrahamCampbell "GrahamCampbell (67 commits)")[![schmittjoh](https://avatars.githubusercontent.com/u/197017?v=4)](https://github.com/schmittjoh "schmittjoh (40 commits)")[![lstrojny](https://avatars.githubusercontent.com/u/79707?v=4)](https://github.com/lstrojny "lstrojny (12 commits)")[![Strate](https://avatars.githubusercontent.com/u/392644?v=4)](https://github.com/Strate "Strate (5 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (2 commits)")[![CViniciusSDias](https://avatars.githubusercontent.com/u/6991415?v=4)](https://github.com/CViniciusSDias "CViniciusSDias (2 commits)")[![asm89](https://avatars.githubusercontent.com/u/657357?v=4)](https://github.com/asm89 "asm89 (2 commits)")[![resurtm](https://avatars.githubusercontent.com/u/100198?v=4)](https://github.com/resurtm "resurtm (1 commits)")[![vanderlee](https://avatars.githubusercontent.com/u/649240?v=4)](https://github.com/vanderlee "vanderlee (1 commits)")[![villfa](https://avatars.githubusercontent.com/u/2891564?v=4)](https://github.com/villfa "villfa (1 commits)")[![cystbear](https://avatars.githubusercontent.com/u/412004?v=4)](https://github.com/cystbear "cystbear (1 commits)")[![erikn69](https://avatars.githubusercontent.com/u/4933954?v=4)](https://github.com/erikn69 "erikn69 (1 commits)")[![matteosister](https://avatars.githubusercontent.com/u/212723?v=4)](https://github.com/matteosister "matteosister (1 commits)")[![muglug](https://avatars.githubusercontent.com/u/2292638?v=4)](https://github.com/muglug "muglug (1 commits)")[![niconoe-](https://avatars.githubusercontent.com/u/9560327?v=4)](https://github.com/niconoe- "niconoe- (1 commits)")[![pborreli](https://avatars.githubusercontent.com/u/77759?v=4)](https://github.com/pborreli "pborreli (1 commits)")

---

Tags

phptypelanguageoption

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[zakirullin/mess

Convenient array-related routine &amp; better type casting

21228.9k2](/packages/zakirullin-mess)[pinkary-project/type-guard

Type Guard module is part of the Pinkary Project, and allows you to \*\*narrow down the type\*\* of a variable to a more specific type.

198102.4k14](/packages/pinkary-project-type-guard)[strictus/strictus

Strict Typing for local variables in PHP

1606.9k](/packages/strictus-strictus)[eftec/minilang

A mini scripting language for php

113.2k2](/packages/eftec-minilang)

PHPackages © 2026

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