PHPackages                             technically/undefined - 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. technically/undefined

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

technically/undefined
=====================

A clever way of having `undefined` type in PHP

1.0.0(3w ago)42↓100%MITPHPPHP ^8.1CI passing

Since May 14Pushed 3w agoCompare

[ Source](https://github.com/technically-php/undefined)[ Packagist](https://packagist.org/packages/technically/undefined)[ RSS](/packages/technically-undefined/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

[![Project logo: image showing an empty circle with dashed border with the text next to it: Technically Undefined](./logo.png)](./logo.png)

Technically\\Undefined
======================

[](#technicallyundefined)

[![Test](https://github.com/technically-php/undefined/actions/workflows/test.yml/badge.svg)](https://github.com/technically-php/undefined/actions/workflows/test.yml)

Technically\\Undefined is a clever way of emulating `undefined` values in PHP8. Thanks to enums and union types we can finally have `undefined` in PHP.

With arrays, you can distinguish between `null` value and *missing key*. However, it is not an option for class properties or typed method parameters.

For typed properties and method parameters you would normally use `null` as "no value". But what do you do if `null` is also a valid value? Then you need another "nullish" thing to use instead. Like `undefined` in JavaScript.

Usage
-----

[](#usage)

The package provides an enum for representing `undefined` values: `Technically\Undefined`.

- You can use it to type class properties and method parameters (e.g. `string | Undefined`)
- You can refer the enum case to define default values to properties and parameters (`Undefined::VALUE`)
- There are several utility methods in the `Undefined` enum which you can use to make your code more elegant

```
use Technically\Undefined;

function hello(string | Undefined $name = Undefined::VALUE) {
  return $name === Undefined::VALUE ? "Hello!" : "Hello, {$name}!";
}
```

Methods
-------

[](#methods)

### `::isUndefined()`

[](#isundefined)

Check if the given value is `Undefined`.

### `::isNotUndefined()`

[](#isnotundefined)

Check if the given value is not `Undefined`.

This method is particularly useful for callbacks:

```
array_filter($array, Undefined::isNotUndefined(...))
```

### `::isNullish()`

[](#isnullish)

Check if the given value is *nullish* — either `null` or `Undefined`.

### `::isNotNullish()`

[](#isnotnullish)

Check if the given value is not *nullish* — neither `null` nor `Undefined`.

This method is particularly useful for callbacks:

```
array_filter($array, Undefined::isNotNullish(...))
```

### `::isEmpty()`

[](#isempty)

Check if the given value is *empty*.

This method follows the semantics of the standard `empty()` function, but also adds support for `Undefined` values — treating them as empty too.

### `::isNotEmpty()`

[](#isnotempty)

Check if the given value is not *empty*.

This method follows the semantics of the standard `empty()` function, but also adds support for `Undefined` values — treating them as empty too.

This method is particularly useful for callbacks:

```
array_filter($array, Undefined::isNotEmpty(...))
```

### `::coalesce()`

[](#coalesce)

Return the first *non-empty* value.

This method follows the semantics of the standard *coalesce operator* in PHP: `?:` (aka "elvis operator"), but also adds support for `Undefined` values — treating them as empty too.

```
return Undefined::coalesce($delay, self::DEFAULT_DELAY);
```

### `::nullishCoalesce()`

[](#nullishcoalesce)

Return the first *non-nullish* value.

This method follows the semantics of the standard *null coalesce operator* in PHP: `??`, but also adds support for `Undefined` values — treating them as nullish too.

```
return Undefined::nullishCoalesce($delay, self::DEFAULT_DELAY);
```

Examples
--------

[](#examples)

### Function parameters

[](#function-parameters)

```
use Technically\Undefined;

function hello(string | null | Undefined $name = Undefined::VALUE) {
    return match ($name) {
        Undefined::VALUE => 'Hello, stranger!',
        null             => 'Hello!',
        default          => "Hello, {$name}!",
    };
}
```

### Class properties

[](#class-properties)

Note how `null` is a possible valid value for updating user organization:

```
use Technically\Undefined;

final readonly class UserUpdateRequest
{
    public function __construct(
        public string | Undefined              $name         = Undefined::VALUE,
        public string | Undefined              $email        = Undefined::VALUE,
        public Organization | null | Undefined $organization = Undefined::VALUE,
    ) {
        // Nothing
    }
}
```

### Immutable objects

[](#immutable-objects)

With `undefined` with can have one big all-in-one "update" method for changing properties of an immutable object:

```
use Technically\Undefined;

readonly class Address {
    public function __construct(
        public string $name,
        public string $line1,
        public string $line2 = '',
        public string $city,
        public string | null $state = null,
        public string $zip,
        public string $country,
    ) {
        // Nothing
    }

    public function with(
        string | Undefined        $name    = Undefined::VALUE,
        string | Undefined        $line1   = Undefined::VALUE,
        string | Undefined        $line2   = Undefined::VALUE,
        string | Undefined        $city    = Undefined::VALUE,
        string | null | Undefined $state   = Undefined::VALUE,
        string | Undefined        $zip     = Undefined::VALUE,
        string | Undefined        $country = Undefined::VALUE,
    ) {
        return new self(
            name:    $name !== Undefined::VALUE    ? $name    : $this->name,
            line1:   $line1 !== Undefined::VALUE   ? $line1   : $this->line1,
            line2:   $line2 !== Undefined::VALUE   ? $line2   : $this->line2,
            city:    $city !== Undefined::VALUE    ? $city    : $this->city,
            state:   $state !== Undefined::VALUE   ? $state   : $this->state,
            zip:     $zip !== Undefined::VALUE     ? $zip     : $this->zip,
            country: $country !== Undefined::VALUE ? $country : $this->country,
        );
    }
}

$address = new Address(
    name:    'Sherlock Holmes',
    line1:   '221B Baker Street',
    city:    'London',
    zip:     'NW1 6XE',
    country: 'England',
);

$address = $address->with(name: 'Dr. John H. Watson');
```

License
-------

[](#license)

This project is licensed under the terms of the [MIT license](./LICENSE).

Credits
-------

[](#credits)

Authored by 👾 [Ivan Voskoboinyk](https://www.voskoboinyk.com/).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance94

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

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.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

26d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/370680?v=4)[Ivan Voskoboinyk](/maintainers/e1himself)[@e1himself](https://github.com/e1himself)

---

Top Contributors

[![e1himself](https://avatars.githubusercontent.com/u/370680?v=4)](https://github.com/e1himself "e1himself (11 commits)")

###  Code Quality

TestsPest

### Embed Badge

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

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

###  Alternatives

[uteq/laravel-query-builder-macros

A set of common Laravel Uteq helpers and macros

201.5k1](/packages/uteq-laravel-query-builder-macros)[jeremytubbs/laravel-deepzoom

Laravel Deepzoom Tile Generator for OpenSeadragon

111.3k](/packages/jeremytubbs-laravel-deepzoom)

PHPackages © 2026

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