PHPackages                             sbwerewolf/language-specific - 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. sbwerewolf/language-specific

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

sbwerewolf/language-specific
============================

Library for using PHP specific features

9.4.3(1mo ago)320.6k↓28.2%11MITPHPPHP &gt;=8.4.1CI passing

Since Oct 7Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/SbWereWolf/language-specific)[ Packagist](https://packagist.org/packages/sbwerewolf/language-specific)[ RSS](/packages/sbwerewolf-language-specific/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (19)Versions (13)Used By (1)

Safe PHP Arrays
===============

[](#safe-php-arrays)

[![Packagist Version](https://camo.githubusercontent.com/e771e853b346af0bacde87dd627eccc5a7fb6b209a262a3e684ec58c4537ddc4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736277657265776f6c662f6c616e67756167652d7370656369666963)](https://packagist.org/packages/sbwerewolf/language-specific)[![Packagist Downloads](https://camo.githubusercontent.com/f02c85dc177f5cf6e53fdfffbab78cb608cafb57361b7548ad66b851b9c1b4a4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736277657265776f6c662f6c616e67756167652d7370656369666963)](https://packagist.org/packages/sbwerewolf/language-specific)[![License](https://camo.githubusercontent.com/869eced93a21a17712f16675ca3f8ec67cbdf705dfb3c0c86c77ccab91adfe4d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f536257657265576f6c662f6c616e67756167652d7370656369666963)](https://github.com/SbWereWolf/language-specific/blob/master/LICENSE)[![CI](https://github.com/SbWereWolf/language-specific/actions/workflows/ci.yml/badge.svg)](https://github.com/SbWereWolf/language-specific/actions/workflows/ci.yml)[![Static Analysis](https://github.com/SbWereWolf/language-specific/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/SbWereWolf/language-specific/actions/workflows/static-analysis.yml)[![Test Coverage](https://camo.githubusercontent.com/1a182f56412afe60d5f8fee6a9adb80510c18e41358f3226d21a6418f416ab31/68747470733a2f2f636f6465636f762e696f2f6769746875622f536257657265576f6c662f6c616e67756167652d73706563696669632f67726170682f62616467652e7376673f746f6b656e3d49373157304146523938)](https://codecov.io/github/SbWereWolf/language-specific)

Read nested arrays safely and cast values predictably in PHP 8.4+

Use it when you need to:

- read nested arrays without long `isset()` (`??`) chains
- normalize request/config payloads with explicit defaults
- keep the “missing value” state visible instead of leaking `null` everywhere

Install
-------

[](#install)

```
composer require sbwerewolf/language-specific
```

Quick example
-------------

[](#quick-example)

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$payload = [
    'user' => [
        'id' => '42',
        'role' => 'admin',
    ],
];
$data = new AdvancedArrayFactory()->makeAdvancedArray($payload);

$userId = $data->pull('user')->get('id')->int(); // 42
$timezone = $data->pull('user')->get('timezone')->default('UTC')->str(); // 'UTC'
// -- OR --
$user = $data->pull('user');

$userId = $user->get('id')->int(); // 42
$timezone = $user->get('timezone')->default('UTC')->str(); // 'UTC'
```

Code test coverage
------------------

[](#code-test-coverage)

[![Codecov graph](https://camo.githubusercontent.com/3ac4a9aa2a77de82b34fdb3b9c0ae15c3c9ec164e198c7cfc22dd3e203f7c5d0/68747470733a2f2f636f6465636f762e696f2f6769746875622f536257657265576f6c662f6c616e67756167652d73706563696669632f6772617068732f747265652e7376673f746f6b656e3d49373157304146523938)](https://camo.githubusercontent.com/3ac4a9aa2a77de82b34fdb3b9c0ae15c3c9ec164e198c7cfc22dd3e203f7c5d0/68747470733a2f2f636f6465636f762e696f2f6769746875622f536257657265576f6c662f6c616e67756167652d73706563696669632f6772617068732f747265652e7376673f746f6b656e3d49373157304146523938)

Quick navigation
----------------

[](#quick-navigation)

- [Killer features](#killer-features)
- [AdvancedArray](#advancedarray)
- [CommonValue](#commonvalue)
- [ArrayFactory](#arrayfactory)
- [CommonArray](#commonarray)
- [BaseArray](#basearray)
- [Factory helpers](#factory-helpers)
- [Native PHP interfaces](#native-php-interfaces)
- [Run tests](#run-tests)

Killer features
---------------

[](#killer-features)

### 1. Safe nested config access

[](#1-safe-nested-config-access)

Use `AdvancedArray` when you need to walk through deeply nested arrays without `isset()` chains and still keep explicit control over missing values.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$config = $factory->makeAdvancedArray([
    'app' => [
        'cache' => [
            'driver' => 'redis',
        ],
    ],
]);

$driver = $config
    ->pull('app')
    ->pull('cache')
    ->get('driver')
    ->default('file')
    ->str();

$driver; // 'redis'

$fallback = $config
    ->pull('app')
    ->pull('queue')
    ->get('driver')
    ->default('sync')
    ->str();

$fallback; // 'sync'
```

Continue with [AdvancedArray](#advancedarray).

### 2. HTTP payload parsing

[](#2-http-payload-parsing)

Use `CommonValue` conversions to normalize request payloads without sprinkling casts across the whole handler.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$payload = $factory->makeAdvancedArray([
    'user' => [
        'id' => '42',
        'is_admin' => '1',
    ],
]);

$userId = $payload->pull('user')->get('id')->int(); // 42
$isAdmin = $payload->pull('user')->get('is_admin')->bool(); // true

$timezone = $payload->pull('user')->get('timezone')->default('UTC')->str();
// 'UTC'
```

Continue with [AdvancedArray](#advancedarray) and [CommonValue](#commonvalue).

### 3. Legacy arrays normalization

[](#3-legacy-arrays-normalization)

Use factories to turn inconsistent old-style data into one predictable API.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$legacy = $factory->makeCommonArray('legacy-value');

$legacy->hasAny(); // true
$legacy->getAny()->str(); // 'legacy-value'
$legacy->get(0)->str(); // 'legacy-value'
```

Continue with [ArrayFactory](#arrayfactory) and [CommonArray](#commonarray).

AdvancedArray
-------------

[](#advancedarray)

Back to [killer features](#killer-features).

### Create an `AdvancedArray` with `makeAdvancedArray()`

[](#create-an-advancedarray-with-makeadvancedarray)

Use `AdvancedArrayFactory` as the main entry point for nested data.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    'service' => [
        'name' => 'Billing',
    ],
]);

$data->isDummy(); // false
$data->pull('service')->get('name')->str(); // 'Billing'
```

### `pull()` returns a nested `AdvancedArrayInterface`

[](#pull-returns-a-nested-advancedarrayinterface)

`pull()` can return the first nested array or a specific nested array by key.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    [
        'config' => [
            'env' => [
                'name' => 'production',
            ],
        ],
    ],
    'meta' => [
        'region' => 'eu',
    ],
]);

$data->pull()->pull('config')->pull('env')->get('name')->str(); // 'production'
$data->pull('meta')->get('region')->str(); // 'eu'
```

### `isDummy()` marks a missing nested array

[](#isdummy-marks-a-missing-nested-array)

Missing nested arrays return a dummy object instead of throwing or leaking `null`.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    'first' => [
        'A' => 1,
    ],
]);

$data->pull('first')->isDummy(); // false
$data->pull('missing')->isDummy(); // true
```

### `get()` reads a value and keeps the missing-state visible

[](#get-reads-a-value-and-keeps-the-missing-state-visible)

`get()` returns a `CommonValueInterface`, so you can inspect both the value and whether the key was actually present.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    'name' => 'Mike',
    'salary' => 19999.99,
]);

$data->get('name')->str(); // 'Mike'
$data->get('salary')->int(); // 19999
$data->get('missing')->asIs(); // null
$data->get('missing')->isReal(); // false
```

### `getAny()` returns the first value or a dummy for an empty collection

[](#getany-returns-the-first-value-or-a-dummy-for-an-empty-collection)

Use `getAny()` when any first available value is good enough.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$filled = $factory->makeAdvancedArray([
    'first' => 'A',
    'second' => 'B',
]);

$filled->getAny()->str(); // 'A'
$filled->getAny()->isReal(); // true

$empty = $factory->makeAdvancedArray([]);

$empty->getAny()->asIs(); // null
$empty->getAny()->isReal(); // false
```

### `has()` checks a specific key

[](#has-checks-a-specific-key)

Use `has()` when you want to know whether a given key exists before reading it.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    0 => 'first',
    'next' => 2,
]);

$data->has(0); // true
$data->has('next'); // true
$data->has('missing'); // false
```

### `hasAny()` checks whether the collection is not empty

[](#hasany-checks-whether-the-collection-is-not-empty)

Use `hasAny()` when you only care whether there is at least one item.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$filled = $factory->makeAdvancedArray([
    'first' => 1,
]);

$filled->hasAny(); // true

$empty = $factory->makeAdvancedArray([]);
$empty->hasAny(); // false
```

### `arrays()` iterates over nested arrays only

[](#arrays-iterates-over-nested-arrays-only)

This is useful when you need to process nested lists without checking each item.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    [
        'name' => 'first',
    ],
    [
        'name' => 'second',
    ],
    'tail',
]);

$names = [];
foreach ($data->arrays() as $nested) {
    $names[] = $nested->get('name')->str();
}

$names; // ['first', 'second']
```

### `values()` iterates over non-array elements only

[](#values-iterates-over-non-array-elements-only)

This is useful when the collection mixes nested arrays with plain scalar values.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    [
        'skip' => true,
    ],
    'first',
    'next',
    'last',
]);

$values = [];
foreach ($data->values() as $value) {
    $values[] = $value->str();
}

$values; // ['first', 'next', 'last']
```

CommonValue
-----------

[](#commonvalue)

Back to [killer features](#killer-features).

### `asIs()` returns the stored value exactly as it is

[](#asis-returns-the-stored-value-exactly-as-it-is)

Use `asIs()` when you want the original stored value without casting.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$value = CommonValueFactory::makeCommonValue([
    'env' => 'prod',
]);

$value->asIs(); // ['env' => 'prod']
```

### `isReal()` and `default()` make missing-state explicit

[](#isreal-and-default-make-missing-state-explicit)

Use `default()` only for missing values; real values stay untouched.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$dummy = CommonValueFactory::makeCommonValueAsDummy();

$dummy->isReal(); // false
$dummy->asIs(); // null
$dummy->default('fallback')->str(); // 'fallback'

$real = CommonValueFactory::makeCommonValue('real value');

$real->isReal(); // true
$real->default('fallback')->str(); // 'real value'
```

### Scalar casts stay close to native PHP casting rules

[](#scalar-casts-stay-close-to-native-php-casting-rules)

Use the typed helpers when you want the cast at the point of reading.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$value = CommonValueFactory::makeCommonValue('1.1');

$value->str(); // '1.1'
$value->int(); // 1
$value->double(); // 1.1
$value->bool(); // true
```

### `array()` turns the current value into an array

[](#array-turns-the-current-value-into-an-array)

This is especially useful when you want one array-shaped read path.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$stringValue = CommonValueFactory::makeCommonValue('release');
$stringValue->array(); // ['release']

$arrayValue = CommonValueFactory::makeCommonValue([
    'env' => 'prod',
]);
$arrayValue->array(); // ['env' => 'prod']
```

### `object()` returns the stored object value

[](#object-returns-the-stored-object-value)

When the stored value is already an object, `object()` returns it unchanged.

```
use SbWereWolf\LanguageSpecific\Value\CommonValue;
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$inner = CommonValueFactory::makeCommonValue(1);
$outer = CommonValueFactory::makeCommonValue($inner);
$object = $outer->object();

$object instanceof CommonValue; // true
$object->asIs(); // 1
```

### `type()` shows all native `gettype()` results used by this library

[](#type-shows-all-native-gettype-results-used-by-this-library)

This example is meant to be read without running it, so every visible result is listed explicitly.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$stream = fopen('php://memory', 'r');

$results = [
    CommonValueFactory::makeCommonValue(null)->type(), //'NULL'
    CommonValueFactory::makeCommonValue(false)->type(), //'boolean'
    CommonValueFactory::makeCommonValue(0)->type(), //'integer'
    CommonValueFactory::makeCommonValue(0.1)->type(), //'double'
    CommonValueFactory::makeCommonValue('a')->type(), //'string'
    CommonValueFactory::makeCommonValue([])->type(), //'array'
    CommonValueFactory::makeCommonValue((object) null)->type(), //'object'
    CommonValueFactory::makeCommonValue($stream)->type(), //'resource'
];

fclose($stream);

$results[] = CommonValueFactory::makeCommonValue($stream)->type();
// 'resource (closed)'

$results;
/*
[
    'NULL',
    'boolean',
    'integer',
    'double',
    'string',
    'array',
    'object',
    'resource',
    'resource (closed)',
]
*/
```

### `class()` shows all native `get_debug_type()` results used by this library

[](#class-shows-all-native-get_debug_type-results-used-by-this-library)

This example includes scalars, arrays, named classes, anonymous classes, resources, and closed resources.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

final class DocumentationNamedExampleClass
{
}

$stream = fopen('php://memory', 'r');
$anonymous = new class () {
};

$results = [
    CommonValueFactory::makeCommonValue(null)->class(), // null
    CommonValueFactory::makeCommonValue(false)->class(), // bool
    CommonValueFactory::makeCommonValue(0)->class(), // int
    CommonValueFactory::makeCommonValue(0.1)->class(), // float
    CommonValueFactory::makeCommonValue('a')->class(), // string
    CommonValueFactory::makeCommonValue([])->class(), // array
    CommonValueFactory::makeCommonValue((object) null)->class(), // stdClass

    CommonValueFactory::makeCommonValue(new DocumentationNamedExampleClass())->class(),
    // DocumentationNamedExampleClass

    CommonValueFactory::makeCommonValue($anonymous)->class(), // class@anonymous
    CommonValueFactory::makeCommonValue($stream)->class(), // resource (stream)
];

fclose($stream);

$results[] = CommonValueFactory::makeCommonValue($stream)->class();
// resource (closed)

$results;
/*
[
    'null',
    'bool',
    'int',
    'float',
    'string',
    'array',
    'stdClass',
    'DocumentationNamedExampleClass',
    'class@anonymous',
    'resource (stream)',
    'resource (closed)',
]
*/
```

ArrayFactory
------------

[](#arrayfactory)

Back to [killer features](#killer-features).

### `makeBaseArray()` wraps any value into a predictable iterable array object

[](#makebasearray-wraps-any-value-into-a-predictable-iterable-array-object)

Use `BaseArray` when you only need the raw iterable container behavior.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$data = $factory->makeBaseArray('legacy-value');

$data->raw(); // ['legacy-value']
```

### `makeCommonArray()` adds `get()` and `has()` on top of the same normalized data

[](#makecommonarray-adds-get-and-has-on-top-of-the-same-normalized-data)

Use `CommonArray` when the data is mostly flat and you want value wrappers.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$data = $factory->makeCommonArray([
    'id' => '42',
    'enabled' => '1',
]);

$data->get('id')->int(); // 42
$data->get('enabled')->bool(); // true
```

CommonArray
-----------

[](#commonarray)

Back to [killer features](#killer-features).

### `get()` reads a specific value

[](#get-reads-a-specific-value)

`get()` returns a `CommonValueInterface`, so missing keys stay observable.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$data = $factory->makeCommonArray([
    'name' => 'Alice',
    'age' => '31',
]);

$data->get('name')->str(); // 'Alice'
$data->get('age')->int(); // 31
$data->get('missing')->isReal(); // false
```

### `getAny()` returns the first value or a dummy for an empty collection

[](#getany-returns-the-first-value-or-a-dummy-for-an-empty-collection-1)

This is the flat-array equivalent of `AdvancedArray::getAny()`.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$filled = $factory->makeCommonArray([
    'first' => 'A',
    'second' => 'B',
]);
$filled->getAny()->str(); // 'A'

$empty = $factory->makeCommonArray([]);
$empty->getAny()->isReal(); // false
```

### `has()` checks a specific key

[](#has-checks-a-specific-key-1)

Use it when you want a lightweight presence check before reading the value.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$data = $factory->makeCommonArray([
    0 => 'first',
    'next' => 2,
]);

$data->has(0); // true
$data->has('next'); // true
$data->has('missing'); // false
```

### `hasAny()` checks whether the collection is not empty

[](#hasany-checks-whether-the-collection-is-not-empty-1)

Use it when you only need to know whether the collection contains any item.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$filled = $factory->makeCommonArray([
    'first' => 1,
]);
$filled->hasAny(); // true

$empty = $factory->makeCommonArray([]);
$empty->hasAny(); // false
```

BaseArray
---------

[](#basearray)

Back to [killer features](#killer-features).

### `raw()` returns the original normalized array

[](#raw-returns-the-original-normalized-array)

Use `raw()` when you need the plain array back without wrappers.

```
use SbWereWolf\LanguageSpecific\Collection\ArrayFactory;

$factory = new ArrayFactory();
$data = $factory->makeBaseArray([
    0 => 'first',
    'index' => 20,
    3 => 'last',
]);

$data->raw();
/*
[
    0 => 'first',
    'index' => 20,
    3 => 'last',
]
*/
```

Factory helpers
---------------

[](#factory-helpers)

Back to [killer features](#killer-features).

### `makeDummyAdvancedArray()` creates a missing nested-array placeholder

[](#makedummyadvancedarray-creates-a-missing-nested-array-placeholder)

Use it when you need a manual dummy object that behaves like a missing nested array.

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$dummy = $factory->makeDummyAdvancedArray();

$dummy->isDummy(); // true
$dummy->hasAny(); // false
```

### `makeCommonValue()` wraps any value into a `CommonValueInterface`

[](#makecommonvalue-wraps-any-value-into-a-commonvalueinterface)

Use it when you want the value-wrapper behavior without creating an array object.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$value = CommonValueFactory::makeCommonValue([
    'region' => 'eu',
]);

$value->array()['region']; // 'eu'
```

### `makeCommonValueAsDummy()` creates a missing-value placeholder

[](#makecommonvalueasdummy-creates-a-missing-value-placeholder)

Use it when the missing-state itself is part of the control flow.

```
use SbWereWolf\LanguageSpecific\Value\CommonValueFactory;

$dummy = CommonValueFactory::makeCommonValueAsDummy();

$dummy->isReal(); // false
$dummy->default('fallback')->str(); // 'fallback'
```

Native PHP interfaces
---------------------

[](#native-php-interfaces)

Back to [killer features](#killer-features).

These features are convenient, but they are not the main reason to use the library.

### Read values with `[]`

[](#read-values-with-)

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    'name' => 'Billing',
    'active' => true,
]);

$data['name']->str(); // 'Billing'
$data['active']->bool(); // true
```

### Iterate with `foreach`

[](#iterate-with-foreach)

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    'name' => 'Billing',
    'active' => true,
]);

$result = [];
foreach ($data as $key => $value) {
    $result[$key] = $value->asIs();
}

$result; // ['name' => 'Billing', 'active' => true]
```

### Serialize the whole object with `json_encode()`

[](#serialize-the-whole-object-with-json_encode)

```
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$factory = new AdvancedArrayFactory();
$data = $factory->makeAdvancedArray([
    'name' => 'Billing',
    'flags' => [
        'active' => true,
    ],
]);

echo json_encode($data, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR);
/*
{
    "name": "Billing",
    "flags": {
        "active": true
    }
}
*/
```

Run tests
---------

[](#run-tests)

```
composer test
```

Documentation examples are executable in:

- `tests/unit/DocumentationExamplesTest.php`

Contacts
--------

[](#contacts)

```
Volkhin Nicholas
e-mail ulfnew@gmail.com
phone +7-902-272-65-35
Telegram @sbwerewolf

```

- [Telegram chat with me](https://t.me/SbWereWolf)
- [WhatsApp chat with me](https://wa.me/79022726535)

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance91

Actively maintained with recent releases

Popularity31

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity79

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

Recently: every ~98 days

Total

11

Last Release

52d ago

Major Versions

5.6.0 → 7.2.02020-10-12

7.2.0 → 8.0.02021-12-31

7.2.1 → 8.4.02025-02-26

8.4.1 → 9.4.12026-03-19

PHP version history (6 changes)7.0.0PHP ~7

5.6.0PHP ~5 || ~7

7.2.0PHP ~7.2

8.0.0PHP &gt;=8.0

8.4.0PHP &gt;=8.4

9.4.1PHP &gt;=8.4.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/56415ea6aeceece7248ce372ec911905cab2cd1313ed2bb4ec8cfacdbaa7d08f?d=identicon)[SbWereWolf](/maintainers/SbWereWolf)

---

Top Contributors

[![SbWereWolf](https://avatars.githubusercontent.com/u/16444541?v=4)](https://github.com/SbWereWolf "SbWereWolf (132 commits)")

---

Tags

arraycomposer-packageconfigdata-normalizationnested-arraysphprequest-parsingtype-casting

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sbwerewolf-language-specific/health.svg)

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

###  Alternatives

[nystudio107/richvariables

Allows you to easily use Craft Globals as variables in Rich Text fields

441.5k](/packages/nystudio107-richvariables)

PHPackages © 2026

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