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

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

typesafepayload/typesafepayload
===============================

A library to navigate and access arbitrary payloads in a type-safe manner

1.6.0(1y ago)0621MITPHPPHP &gt;=8.2

Since Apr 19Pushed 1y ago1 watchersCompare

[ Source](https://github.com/filecage/typesafepayload)[ Packagist](https://packagist.org/packages/typesafepayload/typesafepayload)[ RSS](/packages/typesafepayload-typesafepayload/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (7)Dependencies (3)Versions (8)Used By (0)

Type-Safe Payload
=================

[](#type-safe-payload)

This is a utility for easy, type-safe access to arbitrary data structures. It can be instantiated with any mixed value (payload) and has methods to navigate through structures and access its values in a type-safe manner.

Whenever the payload walker encounters that the requested data can not be retrieved from the given payload, an exception is thrown. This is to keep the type-safe promise: accessing a value with an expected type will always return that value in the expected type *or* throw an exception.

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

[](#installation)

via composer

```
$ composer require typesafepayload/typesafepayload
```

Usage
-----

[](#usage)

### Accessing Data

[](#accessing-data)

#### Example

[](#example)

```
$payload = new TypeSafePayload('any data');
$value = $payload->asString(); // returns `any data`
$value = $payload->asInteger(); // throws because value is not an integer
$value = $payload->asBoolean(); // throws because value is not a boolean
```

#### Data Access Methods

[](#data-access-methods)

- `::asString()` returns payload as `string`
- `::asInteger()` returns payload as `integer`
- `::asBoolean()` returns payload as `boolean`
- `::asStringOrNull()` returns payload as `string` or `null` if empty
- `::asIntegerOrNull()` returns payload as `integer` or `null` if empty
- `::asBooleanOrNull()` returns payload as `boolean` or `null` if empty
- `::asStringList()` returns an array of `string` values
- `::asIntegerList()` returns an array of `integer` values
- `::asBooleanList()` returns an array of `boolean` values
- `::asInstanceOf(string $classOrInterfaceName)` returns an object that is an instance of the given class- or interface name
- `::asInstanceOfOrNull(string $classOrInterfaceName)` returns `null` if property is empty, otherwise an instance of the given class or interface

It's important to note that these methods do **not** cast any types, even if they technically could (e.g. from integer to string). The purpose of this is to ensure a safe protocol between two APIs. If your application allows for APIs where integers and strings are interchangeable, then this is not for you.

However, there is one exception: if the given payload is an object implementing the [`Stringable`](https://php.net/Stringable) interface, this value is accepted.

### Navigating The Structure

[](#navigating-the-structure)

#### Example: Object / Map access

[](#example-object--map-access)

```
$payload = new TypeSafePayload(['foo' => ['bar' => true]]);

$isFooBar = $payload->property('foo')->property('bar')->asBoolean(); // returns `true`
$isBaz = $payload->property('baz')->asBoolean();                     // throws because property baz does not exist
```

#### Example: List Access

[](#example-list-access)

```
$payload = new TypeSafePayload(['coordinates' => [12, 23]]);
$x = $payload->property('coordinates')->index(0)->asInteger(); // returns `12`
$y = $payload->property('coordinates')->index(1)->asInteger(); // returns `23`
$z = $payload->property('coordinates')->index(2)->asInteger(); // throws because index 2 is not set
```

#### Data Navigation Methods

[](#data-navigation-methods)

- `::property(string $key)` returns a payload walker for the values of the sub-property `$key`
- `::index(int $index)` returns a payload walker for the values of the index `$index`
- `::iterate()` returns an iterator for each value of the current payload
- `::isEmpty()` returns `true` if the current payload is empty (empty meaning `null` or no value at all)

### Modifying The Data

[](#modifying-the-data)

- `::fillEmpty(mixed $value)` fills the current payload with `$value` if it's empty

Exception Management
--------------------

[](#exception-management)

By default, an exception of type [`BadPayloadException`](src/BadPayloadException.php) is thrown. This behaviour can be controlled by passing a [`ThrowableFactory`](src/ThrowableFactory.php)in order to use userland exception types instead. This is useful to avoid having to catch library exceptions and throw a new one again.

The `ThrowableFactory` has to be passed to the `TypesafePayload` instance:

```
$throwableFactory = new class implements \TypesafePayload\TypesafePayload\ThrowableFactory {
    public function createThrowable(string $expectedType, string $actualType, int|string|null $payloadVariable = null,string|int ...$payloadVariableSubPath) : Throwable {
        // see example below to understand $payloadVariable and $payloadVariableSubPath
        return new MyCustomException("Payload Error: Expected type $expectedType but got $actualType instead");
    }
}

$payload = new TypesafePayload\TypesafePayload\TypesafePayload("my arbitrary payload", $throwableFactory);
```

Warning

Don't throw from the `ThrowableFactory` as this will clutter the stack trace

### Payload Variable Path

[](#payload-variable-path)

The `$payloadVariable` and `$payloadVariableSubPath` contain the property and/or index path that was used to access the current payload where `string` means property access and `int` means index access.

```
$somePayload = (object) ['foo' => ['bar' => ['baz', 'boo']]];
$payload = new \TypesafePayload\TypesafePayload\TypesafePayload($somePayload);

// throws with `$payloadVariable` being `foo` and `$payloadVariableSubPath` being `bar`, `2` (as integer)
$payload->property('foo')->property('bar')->index(2)->asBoolean();

// to turn this into a human-readable string, use `BadPayloadException::formatVariablePath()`:
echo \TypesafePayload\TypesafePayload\BadPayloadException::formatVariablePath('foo', 'bar', 2);
// formats to `$foo->bar[2]`
```

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance31

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity62

Established project with proven stability

 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

Every ~67 days

Recently: every ~91 days

Total

7

Last Release

717d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/698854?v=4)[David](/maintainers/filecage)[@filecage](https://github.com/filecage)

---

Top Contributors

[![filecage](https://avatars.githubusercontent.com/u/698854?v=4)](https://github.com/filecage "filecage (21 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[rubix/ml

A high-level machine learning and deep learning library for the PHP language.

2.2k1.4M28](/packages/rubix-ml)[arcanedev/qr-code

QR Code generator

1231.9k1](/packages/arcanedev-qr-code)[bestmomo/laravel5-3-installer

Helper for Laravel 5.3 application installation

174.7k](/packages/bestmomo-laravel5-3-installer)

PHPackages © 2026

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