PHPackages                             modethirteen/type-ex - 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. modethirteen/type-ex

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

modethirteen/type-ex
====================

A collection of useful behavior extensions for PHP

1.2.0(5y ago)03.2k12Apache-2.0PHPPHP ^7.2.0

Since Dec 19Pushed 4y ago1 watchersCompare

[ Source](https://github.com/modethirteen/TypeEx)[ Packagist](https://packagist.org/packages/modethirteen/type-ex)[ RSS](/packages/modethirteen-type-ex/feed)WikiDiscussions main Synced 6d ago

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

TypeEx
======

[](#typeex)

A collection of useful behavior extensions for PHP

[![github.com](https://github.com/modethirteen/TypeEx/workflows/build/badge.svg)](https://github.com/modethirteen/TypeEx/actions?query=workflow%3Abuild)[![codecov.io](https://camo.githubusercontent.com/61f247ad7e20eb77ee0dd82912702dd06f6faa65edad63aaad750c820899fcd5/68747470733a2f2f636f6465636f762e696f2f6769746875622f6d6f6465746869727465656e2f5479706545782f636f7665726167652e7376673f6272616e63683d6d61696e)](https://codecov.io/github/modethirteen/TypeEx?branch=main)[![Latest Stable Version](https://camo.githubusercontent.com/52746b5149e6af0000ee7b229020c3628ef9af3a6e33895cb00200cc3eb34c13/68747470733a2f2f706f7365722e707567782e6f72672f6d6f6465746869727465656e2f747970652d65782f76657273696f6e2e737667)](https://packagist.org/packages/modethirteen/type-ex)[![Latest Unstable Version](https://camo.githubusercontent.com/86c55c8477fbd104ea768f7052d15bba938b39d3fb89c3cc3b10f313d8af1aad/68747470733a2f2f706f7365722e707567782e6f72672f6d6f6465746869727465656e2f747970652d65782f762f756e737461626c65)](https://packagist.org/packages/modethirteen/type-ex)

Requirements
------------

[](#requirements)

- PHP 7.4 (main, 2.x)

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

[](#installation)

Use [Composer](https://getcomposer.org/). There are two ways to add TypeEx to your project.

From the composer CLI:

```
./composer.phar require modethirteen/type-ex
```

Or add modethirteen/type-ex to your project's composer.json:

```
{
    "require": {
        "modethirteen/type-ex": "dev-main"
    }
}
```

`dev-main` is the main development branch. If you are using TypeEx in a production environment, it is advised that you use a stable release.

Assuming you have setup Composer's autoloader, TypeEx can be found in the `modethirteen\TypeEx\` namespace.

Usage
-----

[](#usage)

### Dictionary

[](#dictionary)

```
// a collection builder with optional validation of set values (type checks, etc.)
$dictionary = new Dictionary(function($value) : bool {

    // enforce a collection of integer values only
    return is_int($value);
});
$dictionary->set('foo', 123);
$dictionary->set('bar', 'xyzzy'); // throws InvalidDictionaryValueException

// dictionaries are iterable
foreach($dictionary as $key => value) { }

// ...and the underlying array data structure is accessible
$dictionary->toArray(); // ['foo' => 123]
```

### StringDictionary

[](#stringdictionary)

```
// a collection builder that leverages PHP-native type checking to enforce string types only
$dictionary = new StringDictionary();
$dictionary->set('bar', 'xyzzy');

// string dictionaries are iterable
foreach($dictionary as $key => value) { }

// ...and the underlying array data structure is accessible
$dictionary->toArray(); // ['foo' => 'xyzzy']
```

### StringEx

[](#stringex)

```
// check for empty strings with strict type checking
StringEx::isNullOrEmpty(null); // true
StringEx::isNullOrEmpty(''); // true
StringEx::isNullOrEmpty('foo'); // false

// convert any value to a string, with some slightly different rules than strval(...)
StringEx::stringify(null); // ''
StringEx::stringify('foo'); // 'foo'
StringEx::stringify(true); // 'true'
StringEx::stringify(false); // 'false'
StringEx::stringify(123); // '123'

// array values are serialized to comma separated lists by default
StringEx::stringify(['foo', 'bar']); // 'foo,bar'
StringEx::stringify(['foo', 'plugh', 'bar' => ['baz']]); // 'foo,plugh,baz'

// ...however a custom serializer can apply any collection serialization
StringEx::stringify(['foo', 'bar'], function($value) {

    // how about JSON?
    return json_encode($value);
}); // '["foo","bar"]'

// a default custom serializer can also be set for all subsequent stringify operations
class MyClass {
    public function toString() : string {
        return 'foo';
    }
}
StringEx::setDefaultSerializer(function($value) {
    return $value instanceof MyClass ? $value->toString() : 'xyzzy';
});
StringEx::stringify(new MyClass()); // 'foo'
StringEx::stringify(['foo', 'bar']); // 'xyzzy'

// more complex collection serialization strategies can also be implemented
StringEx::setDefaultSerializer(function($value) : string {
    $xml = '';
    foreach($value as $item) {
        $item = StringEx::stringify($item);
        $xml .= "{$item}";
    }
    return "{$xml}";
});
StringEx::stringify(['foo', 'bar', 'baz' => ['a', 'b', 'c']]);
```

```

    foo
    bar

            a
            b
            c

```

```
// setting the default serializer globally on StringEx may be dangerous if other included projects or components rely on the class
class ExtendedCustomStringEx extends StringEx {

    /**
     * Add a static::$serializer to your extended class and late static binding will ensure any
     * default serializer you set will not affect any components relying directly on StringEx
     *
     * @var Closure|null
     */
    protected static $serializer = null;
}
ExtendedCustomStringEx::setDefaultSerializer(function() {
    return 'foo';
});

// the value of anonymous functions are stringified
StringEx::stringify(function() { return 'foo'; }); // 'foo'
StringEx::stringify(function() { return 123; }); // '123'
StringEx::stringify(function() { return ['foo', 'bar']; }); // 'foo,bar'
StringEx::stringify(function() { return ['foo', 'plugh', 'bar' => ['baz']]; }); // 'foo,plugh,baz'

// objects, as expected, have __toString called (even objects returned from anonymous functions)
StringEx::stringify(function() { return new class { function __toString() : string { return 'xyzzy'; }}; }); // 'xyzzy'
StringEx::stringify(new class { function __toString() : string { return 'qux'; }}); // 'qux'

// if an object does not have a __toString method, the object is serialized with native PHP serialization or the output of the custom/default serializer
class Bar {
    public $foo = ['baz', 'qux'];
}
StringEx::stringify(new Bar()); // 'O:3:"Bar":1:{s:3:"foo";a:2:{i:0;s:3:"baz";i:1;s:3:"qux";}}'

// check if a string contains a sub-string value
(new StringEx('foo bar'))->contains('foo'); // true
(new StringEx('baz'))->contains('foo'); // false

// check if a string ends with a sub-string value
(new StringEx('foo bar'))->endsWith('bar'); // true
(new StringEx('foo bar'))->endsWith('qux'); // false
(new StringEx('foo bar'))->endsWithInvariantCase('BAR'); // true

// check if a string starts with a sub-string value
(new StringEx('foo bar'))->startsWith('foo'); // true
(new StringEx('foo bar'))->startsWith('qux'); // false
(new StringEx('foo bar'))->startsWithInvariantCase('FOO'); // true

// check if a string equals value
(new StringEx('foo bar'))->equals('foo bar'); // true
(new StringEx('foo bar'))->equals('foo BAR'); // false
(new StringEx('foo bar'))->equalsInvariantCase('foo BAR'); // true

// an immutable string manipulation API for removing, trimming, and templating
$replacements = new StringDictionary();
$replacements->set('bar', 'frank');
$replacements->set('qux', 'jesse');
$string = (new StringEx('foo {{bar}} baz {{qux}} plugh xyzzy'))
    ->removePrefix('foo')
    ->trim()
    ->interpolate($replacements);

// trimming and adding ellipsis attempts to break on words
$string->ellipsis(20)->toString(); // 'frank baz jesse …'
$string->ellipsis(25)->toString(); // 'frank baz jesse plugh …'

// base64 encoding and decoding
(new StringEx('foo bar baz qux'))->encodeBase64()->toString(); // 'Zm9vIGJhciBiYXogcXV4'
(new StringEx('Zm9vIGJhciBiYXogcXV4'))->decodeBase64()->toString(); // 'foo bar baz qux'
(new StringEx('🐇🐇🐇'))->decodeBase64(true)->toString(); // throws StringExCannotDecodeBase64StringException
```

### BoolEx

[](#boolex)

```
// convert any value to a boolean, with some slightly different rules than boolval(...)
BoolEx::boolify(true); // true
BoolEx::boolify(false); // false

// strings are literally checked for the word "true" in order to return a true value
BoolEx::boolify(null); // false
BoolEx::boolify('foo'); // false
BoolEx::boolify(function() { return null; }); // false
BoolEx::boolify(function() { return 'foo'; }); // false
BoolEx::boolify(new class { function __toString() : string { return 'true'; }}); // true
BoolEx::boolify(new class { function __toString() : string { return 'false'; }}); // false
BoolEx::boolify(function() { return new class { function __toString() : string { return 'true'; }}; }); // true
BoolEx::boolify(function() { return new class { function __toString() : string { return 'false'; }}; }); // false

// any numeric above 0, or any string that appears to be numeric above 0, is true
BoolEx::boolify(function() { return 123; }); // true
BoolEx::boolify(123); // true
BoolEx::boolify('123'); // true
BoolEx::boolify('-5'); // false
BoolEx::boolify('0.1'); // true
BoolEx::boolify('0'); // false
BoolEx::boolify('0.0'); // false

// arrays, or functions and objects that return arrays, are the same behavior as boolval(...): if the collection is empty the value is false
BoolEx::boolify(function() { return ['foo', 'bar']; }); // true
BoolEx::boolify(function() { return ['foo', 'plugh', 'bar' => ['baz']]; }); // true
BoolEx::boolify(['foo', 'bar']); // true
BoolEx::boolify(['foo', 'plugh', 'bar' => ['baz']]); // true
BoolEx::boolify([]); // false
BoolEx::boolify(['foo' => []]); // true
```

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity18

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity50

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

Total

3

Last Release

1960d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2bfdbec0ff13b1d7836c00d751876485508071cf26e6dcc2bae7fb7333b6f40f?d=identicon)[modethirteen](/maintainers/modethirteen)

---

Top Contributors

[![modethirteen](https://avatars.githubusercontent.com/u/45862?v=4)](https://github.com/modethirteen "modethirteen (34 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/modethirteen-type-ex/health.svg)

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

###  Alternatives

[olifanton/ton

PHP library for The Open Network blockchain

8849.8k2](/packages/olifanton-ton)[bigwhoop/sentence-breaker

Sentence boundary disambiguation (SBD) - or sentence breaking - library written in PHP.

42132.3k](/packages/bigwhoop-sentence-breaker)[mwhite/random-uagent

A library for generating random User Agents

2353.4k2](/packages/mwhite-random-uagent)

PHPackages © 2026

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