PHPackages                             ft/utils - 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. ft/utils

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

ft/utils
========

A package of personal utilities for PHP

02PHP

Since Feb 18Pushed 3y ago1 watchersCompare

[ Source](https://github.com/soulshined/ft-utils)[ Packagist](https://packagist.org/packages/ft/utils)[ RSS](/packages/ft-utils/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

`> composer require ft/utils:dev-master`

FT\\Utils\\Optional
-------------------

[](#ftutilsoptional)

A class for working with nullable values.

An implementation emulating Javas `Optional`

 ```
classDiagram
    class Optional {
        of(mixed $value) Optional
        ofNullable(mixed $value) Optional
        absent() Optional
        get() mixed
        isPresent() bool
        ifPresent(callable $consumer) void
        ifPresentOrElse(callable $consumer, callable $else) void
        orElse(mixed $else) mixed
        orElseThrow(?Throwable $throwable = null) mixed
        map(callable $mapper) Optional
        equals($object) bool
    }
```

      Loading See `tests/OptionalTest.php` for usage examples and intentions

FT\\Utils
---------

[](#ftutils)

### Functions

[](#functions)

- `last(mixed $value, ?callable $predicate = null, ?int $qty = null) : mixed`

    Retrieve the last component of a given element

    ```
    Utils::last(['a','b','c']); // 'c'
    Utils::last(['a','b','c'], qty: 2); //['b','c']
    Utils::last(['a val','b val','c val'], fn($i) => str_starts_with($i, 'b'), qty: 2); // ['b val']
    Utils::last([['key' => 'value', 'foo' => 'bar']]); //['foo' => 'bar']
    Utils::last("foobar"); // 'r'
    Utils::last("foobar", 3); // 'bar'

    $class = new class {
        public function __construct(
            public readonly $foo = "bar",
            public readonly $bazz = "buzz"
        )
    }
    Utils::last($class); // ['bazz' => 'buzz']
    ```
- first

    Retrieve the first component of a given element

    ```
    Utils::first(['a','b','c']); // 'a'
    Utils::first(['a','b','c'], qty: 2); //['a','b']
    Utils::first(['a val','b val','c val'], fn($i) => str_starts_with($i, 'b'), qty: 2); // ['b val']
    Utils::first([['key' => 'value', 'foo' => 'bar']]); //['key' => 'value']
    Utils::first("foobar"); // 'f'
    Utils::first("foobar", 3); // 'foo'

    $class = new class {
        public function __construct(
            public readonly $foo = "bar",
            public readonly $bazz = "buzz"
        )
    }
    Utils::first($class); // ['foo' => 'bar']
    ```
- guidv4

### Arrays

[](#arrays)

- `flatten(array $haystack, int $depth = 1) : array`

    ```
    $arr = [[1,2,3],[4,5,6],[7,[8,9]]];
    Utils::$Array::flatten($arr); //[1,2,3,4,5,6,7,[8,9]]
    ```
- `anyMatch(array $haystack, callable $predicate) : bool`

    ```
    $arr = [1,2,3,4,5]
    Utils::$Array::anyMatch($arr, 'is_int'); //true
    Utils::$Array::anyMatch($arr, 'is_string'); //false
    ```
- `allMatch(array $haystack, callable $predicate) : bool`

    ```
    $arr = [1,2,3,4,5]
    Utils::$Array::allMatch($arr, 'is_int'); //true
    Utils::$Array::allMatch($arr, fn($i) => $i > 3); //false
    ```
- `noneMatch(array $haystack, callable $predicate) : bool`

    ```
    $arr = [1,2,3,4,5]
    Utils::$Array::noneMatch($arr, 'is_int'); //false
    Utils::$Array::noneMatch($arr, 'is_string'); //true
    ```
- `assc_array_map(array $haystack, callable $callback): array`

    ```
    $headers = [
        'Content-Type' => 'application/json',
        'Accept' => 'application/json'
    ];
    Utils::$Array::assc_array_map($headers, fn ($k, $v) => "$k: $v");
    /*
        ['Content-Type: application/json', 'Accept: application/json']
    */
    ```
- `find_by_property_values(array $haystack, array $pvps) : mixed`

    Returns the first found element that matches the given criteria

    ```
    class User {
        public function __construct(
            public readonly string $fname,
            public readonly string $lname,
            public readonly int $age,
        )
    }

    $users = [
        new User('john', 'doe', 99),
        new User('jane', 'doe', 77),
        new User('jerry', 'doe', 88)
    ];

    Utils::$Array::find_by_property_values($users, ['lname', 'doe']);
    // object(fname=john,lname=doe,age=99)

    Utils::$Array::find_by_property_values($users, ['lname' => 'doe', 'fname' => 'jerry']);
    // object(fname=jerry,lname=doe,age=88)
    ```
- `sort_by_property(array &$haystack, string $property, string $direction = 'asc')`

    Sorts an array of objects by a property

    ```
    class User {
        public function __construct(
        public readonly string $fname,
        public readonly string $lname,
        public readonly int $age,
    )
    }

    $users = [
        new User('john', 'doe', 99),
        new User('jane', 'doe', 77),
        new User('jerry', 'doe', 88)
    ];

    Utils::$Array::sort_by_property($users, 'age');
    /*
        [
            object(fname=jane),
            object(fname=jerry),
            object(fname=john)
        ]
    */

    Utils::$Array::sort_by_property($users, 'age', 'desc');
    /*
        [
            object(fname=john),
            object(fname=jerry),
            object(fname=jane)
        ]
    */
    ```
- `sort_by_value_key(array &$haystack, string $key, string $direction = 'asc')`

    Sorts an array of values by a value key

    ```
    $users = [
        [
            'fname' => 'john',
            'lname' => 'doe',
            'age' => 99
        ],
        [
            'fname' => 'jane',
            'lname' => 'doe',
            'age' => 77
        ],
        [
            'fname' => 'jerry',
            'lname' => 'doe',
            'age' => 88
        ]
    ];

    Utils::$Array::sort_by_value_key($users, 'age');
    /*
        [
            array(fname=jane),
            array(fname=jerry),
            array(fname=john)
        ]
    */

    Utils::$Array::sort_by_value_key($users, 'age', 'desc');
    /*
        [
            array(fname=john),
            array(fname=jerry),
            array(fname=jane)
        ]
    */
    ```

### Path

[](#path)

- `join(string ...$segments): string`

    Join paths using native `DIRECTORY_SEPARATOR` constant
- `scan_for_files(string $directory, string $file_regexp, array $ignore = []): array`

    Scan for files *recursively* in a given directory that match a given pattern. Returns an array of `SplFileInfo`

    This supports ignoring files

    > **Note** The `/` in the ignore patterns do not need to be escaped
    >
    > All paths get converted to a real path and all separators get converted to a forward slash `/`

    ```
    //return all php files
    Utils::$Path::scan_for_files(__DIR__, "\.php$");
    Utils::$Path::scan_for_files(__DIR__, "\.php$",
        ignore: ['/vendor/?.*']
    );
    ```
- `getFileSystemIteratorFilter`

    This custom FileSystemIterator allows ignoring patterns (ignoring is leaf type agnostic, the pattern will validate against directories and paths)

    FileSystemIterator constructor

    ```
    public function __construct(
        RecursiveIterator $iterator,
        private readonly array $ignore = []
    ) {}
    ```

    FileSystemIterator example usage

    ```
    $dir_it = new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS);
    $fs_it = Utils::$Path::getFileSystemIteratorFilter($dir_it, $ignore_array);
    ```

### Preg

[](#preg)

- `count(string $pattern, string $subject, int $flags = 0, int $offset = 0) : int`

    Returns the number matches for a given a pattern

    This is guaranteed to return an integer
- `match_all(string $pattern, string $subject, &$matches, int $flags = 0, int $offset = 0)`

    Return all matches of a given pattern

    ```
    $str = value; // https://johndoe:pa$$w0rd@example.com
    $john_match->start; // 0
    $john_match->end; // 36

    //accessing groups
    $john_match->groups->{'1'}; // johndoe
    $john_match->groups->username; // johndoe
    $john_match->g1; //johndoe

    $john_match->groups->{'2'}; // pa$$w0rd
    $john_match->groups->password; // pa$$w0rd
    $john_match->g2; //pa$$w0rd
    ```

### Strings

[](#strings)

- `charAt(string $value, int $index) : ?string`
- `utf8(string $value): ?string`
- `explode_implode( string $value, string $explode_delimiter, ?callable $foreach = null, ?string $implode_delimiter = null, int $limit = PHP_INT_MAX ) : string`

    Utility to quickly explode a string, optionally perform a mapping operation on each value and then implode it back

    > **Note** the foreach map is applied to the exploded operation

    ```
    $str = "key=value; key2=value2; key3=value3";

    $result = Utils::$String::explode_implode(
        $str,
        explode_delimiter: ";",
        implode_delimiter: " / ",
        foreach: fn($i) =>
            Utils::$String::explode_implode($i, "=", null, " => ")
    );

    echo $result; // "key => value /  key2 => value2 /  key3 => value3"
    ```

###  Health Score

14

—

LowBetter than 2% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity2

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity23

Early-stage or recently created project

 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1a9ec50a967899163d0d22508c6e3b72b930f51e2d36213ac0bc782910ad46a2?d=identicon)[davidfreer](/maintainers/davidfreer)

---

Top Contributors

[![soulshined](https://avatars.githubusercontent.com/u/11242654?v=4)](https://github.com/soulshined "soulshined (1 commits)")

### Embed Badge

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

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

###  Alternatives

[pingpong/shortcode

Laravel - Simple shortcode based on wordpress shortcode

4040.0k1](/packages/pingpong-shortcode)[marineusde/larapex-charts

Package to provide easy api to build apex charts on Laravel

1214.2k](/packages/marineusde-larapex-charts)[concretecms/migration_tool

Import content into your concrete5 sites. Cross-grade from version 5.6, 5.7 and more.

102.1k](/packages/concretecms-migration-tool)

PHPackages © 2026

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