PHPackages                             nitier/caster - 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. nitier/caster

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

nitier/caster
=============

Strict, convenient casting helpers for PHP (mixed -&gt; typed).

1.0.1(5mo ago)041MITPHPPHP &gt;=8.1

Since Nov 28Pushed 5mo agoCompare

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

READMEChangelog (2)Dependencies (4)Versions (3)Used By (1)

Caster
======

[](#caster)

Strict and expressive casting helpers for PHP. The goal is to replace chains of `isset`, `is_*`and ad-hoc checks with a single call that either returns a typed value or throws a descriptive exception.

Features
--------

[](#features)

- Scalar casters (`int`, `float`, `bool`, `string`, `nonEmptyString`, trimmed variants, etc.).
- Date/time helpers for `DateTimeImmutable`.
- Enum support for backed enums (`enum`, `nullableEnum`, `tryEnum`).
- Array utilities (`listOf`, `arrayOf`, nullable and try-\* variants).
- JSON decoding with validation.
- Payload facades (`fromArray`, `fromArrayNullable`) to extract and cast fields in one step.
- “Soft” `try*` methods that return `null` on failure instead of throwing.
- Convenience guards (`required`, `requiredNonEmptyString`, `requiredNonEmptyList`, …).

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

[](#installation)

```
composer require nitier/caster
```

Basic Usage
-----------

[](#basic-usage)

```
use Nitier\Caster\Caster;

$payload = [
    'id' => '42',
    'price' => '19.95',
    'active' => 'yes',
    'created_at' => '2024-05-10 12:00:00',
];

$id = Caster::positiveInt($payload['id']);                 // 42
$price = Caster::float($payload['price']);                 // 19.95
$isActive = Caster::bool($payload['active']);              // true
$createdAt = Caster::dateTimeImmutable($payload['created_at']);
```

If casting fails, a `CastException` is thrown with field context (when provided). Nullable variants (`nullableInt`, `nullableFloat`, …) treat `null` and whitespace-only strings as “empty”.

### Strings and Booleans

[](#strings-and-booleans)

```
$slug = Caster::nonEmptyTrimmedString($payload['slug']);   // trims and rejects empty results
$alias = Caster::nullableString($payload['alias'] ?? null); // ?string
$flag = Caster::bool('Yes');                               // true
$maybeFlag = Caster::tryBool('unknown');                   // null
```

### Date &amp; Time

[](#date--time)

```
$publishedAt = Caster::dateTimeImmutable('2024-01-01T10:00:00+00:00');
$maybeExpires = Caster::nullableDateTimeImmutable(
    $payload['expires_at'] ?? null,
    'expires_at',
    DATE_ATOM
);
```

### Enums

[](#enums)

```
enum Status: string { case Draft = 'draft'; case Published = 'published'; }

$status = Caster::enum(Status::class, 'draft');        // Status::Draft
$maybeStatus = Caster::tryEnum(Status::class, 'oops'); // null
```

Soft `try*` Helpers
-------------------

[](#soft-try-helpers)

When you prefer a nullable result over exceptions:

```
$maybeAge = Caster::tryInt($payload['age'] ?? null);        // ?int
$maybeActive = Caster::tryBool($payload['active'] ?? null); // ?bool
$maybeDate = Caster::tryDateTimeImmutable($payload['published_at'] ?? null);
```

Each `try*` helper wraps the strict version and returns `null` on failure.

Payload Helpers
---------------

[](#payload-helpers)

Extract values from an associative array and cast them on the spot:

```
$payload = [
    'id' => '100',
    'name' => 'Alice',
    'meta' => ['role' => 'admin'],
    'tags' => ['php', 'caster'],
];

$id = Caster::fromArray($payload, 'id', [Caster::class, 'positiveInt']);
$name = Caster::fromArrayNullable($payload, 'name', [Caster::class, 'nonEmptyTrimmedString']);
$meta = Caster::requiredNonEmptyArray(
    $payload['meta'] ?? null,
    'meta',
    static fn ($value) => Caster::string($value)
);
$tags = Caster::requiredNonEmptyList(
    $payload['tags'] ?? null,
    'tags',
    static fn ($value) => Caster::nonEmptyTrimmedString($value)
);
```

- `fromArray` throws `MissingValueException` when the key is missing.
- `fromArrayNullable` returns `null` when the key is missing or empty.
- `requiredNonEmpty*` helpers ensure presence and non-empty content for strings/lists/maps.

Collections
-----------

[](#collections)

`listOf` and `arrayOf` accept a caster callback applied to every item:

```
$ids = Caster::listOf(['1', '2', '3'], static fn ($value) => Caster::int($value));
$attributes = Caster::arrayOf(
    ['a' => 'true', 'b' => 'false'],
    static fn ($value) => Caster::bool($value)
);

// Nullable variants return null for missing/empty input
$maybeTags = Caster::nullableListOf($payload['tags'] ?? null, static fn ($v) => Caster::string($v));
```

Use `requiredNonEmptyList`/`requiredNonEmptyArray` when the collection must contain at least one item.

JSON
----

[](#json)

```
$data = Caster::json($payload['data']);            // array
$maybeData = Caster::tryJson($payload['data']);    // ?array
```

You can pass `$assoc`, `$depth` and `$flags` just like `json_decode`.

Required Guards
---------------

[](#required-guards)

`Caster::required($value, 'field')` ensures a value is not `null`. For common cases you can use:

```
$name = Caster::requiredNonEmptyString($payload['name'] ?? null, 'name', true);
$options = Caster::requiredNonEmptyArray(
    $payload['options'] ?? null,
    'options',
    static fn ($value) => Caster::string($value)
);
```

Testing
-------

[](#testing)

The project includes an extensive PHPUnit suite. Run it with:

```
composer test
```

Static analysis:

```
composer stan
```

Code style:

```
composer cs
```

License
-------

[](#license)

MIT ©2025 Nitier

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance70

Regular maintenance activity

Popularity3

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity45

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

Every ~0 days

Total

2

Last Release

171d ago

### Community

Maintainers

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

---

Top Contributors

[![Nitier](https://avatars.githubusercontent.com/u/185420306?v=4)](https://github.com/Nitier "Nitier (5 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

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

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

PHPackages © 2026

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