PHPackages                             ipl/stdlib - 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. ipl/stdlib

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

ipl/stdlib
==========

ipl Standard Library

v0.16.0(2d ago)0163.5k↓43.9%3[9 issues](https://github.com/Icinga/ipl-stdlib/issues)[8 PRs](https://github.com/Icinga/ipl-stdlib/pulls)7MITPHPPHP &gt;=8.2CI passing

Since Mar 26Pushed 3w ago7 watchersCompare

[ Source](https://github.com/Icinga/ipl-stdlib)[ Packagist](https://packagist.org/packages/ipl/stdlib)[ RSS](/packages/ipl-stdlib/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (4)Versions (35)Used By (7)

Icinga PHP Library - Standard Library
=====================================

[](#icinga-php-library---standard-library)

`ipl/stdlib` provides reusable building blocks for Icinga PHP libraries and applications. It covers declarative filtering, event emission, string and iterable utilities, lightweight data and message containers, and a stable priority queue.

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

[](#installation)

The recommended way to install this library is via [Composer](https://getcomposer.org):

```
composer require ipl/stdlib
```

`ipl/stdlib` requires PHP 8.2 or later with the `openssl` extension.

Usage
-----

[](#usage)

### Filter Rows With Declarative Rules

[](#filter-rows-with-declarative-rules)

Build composable filter trees with `ipl\Stdlib\Filter` and evaluate them against arrays or objects:

```
use ipl\Stdlib\Filter;

$filter = Filter::all(
    Filter::equal('problem', '1'),
    Filter::none(Filter::equal('handled', '1')),
    Filter::like('service', 'www.*')
);

$row = [
    'problem' => '1',
    'handled' => '0',
    'service' => 'www.icinga.com',
];

if (Filter::match($filter, $row)) {
    // The row matches the rule set.
}
```

Available condition factories: `equal`, `unequal`, `like`, `unlike`, `greaterThan`, `greaterThanOrEqual`, `lessThan`, `lessThanOrEqual`. Available logical factories: `all`, `any`, `none`, `not`.

### Build Filters Incrementally

[](#build-filters-incrementally)

When an object needs to collect filter conditions over time, use the `Filters`trait. It complements the `Filterable` contract and exposes `filter()`, `orFilter()`, `notFilter()`, and `orNotFilter()`:

```
use ipl\Stdlib\Contract\Filterable;
use ipl\Stdlib\Filter;
use ipl\Stdlib\Filters;

class Query implements Filterable
{
    use Filters;
}

$query = (new Query())
    ->filter(Filter::equal('problem', '1'))
    ->orNotFilter(Filter::equal('handled', '1'));

$filter = $query->getFilter();
```

Events
------

[](#events)

The `Events` trait wraps [Evenement](https://github.com/igorw/evenement) and adds event validation. Declare event name constants on the class to give callers a typo-safe API and to let `isValidEvent()` enforce an explicit allow-list:

```
use ipl\Stdlib\Events;

class Connection
{
    use Events;

    public const ON_CONNECT = 'connected';
    public const ON_DISCONNECT = 'disconnected';

    protected function isValidEvent($event): bool
    {
        return in_array($event, [static::ON_CONNECT, static::ON_DISCONNECT], true);
    }

    public function open(): void
    {
        // ... connect ...
        $this->emit(self::ON_CONNECT, [$this]);
    }

    public function close(): void
    {
        // ... disconnect ...
        $this->emit(self::ON_DISCONNECT, [$this]);
    }
}

$conn = new Connection();
$conn->on(Connection::ON_CONNECT, function (Connection $c): void {
    echo "Connected\n";
});
$conn->on(Connection::ON_DISCONNECT, function (Connection $c): void {
    echo "Disconnected\n";
});

$conn->open();
$conn->close();
```

Utility Helpers
---------------

[](#utility-helpers)

### Str

[](#str)

`Str` offers string utilities that complement PHP's built-in functions. It converts between naming conventions, splits and trims in one step, and provides `startsWith` with case-insensitive matching.

```
use ipl\Stdlib\Str;

// Convert snake_case or kebab-case identifiers to camelCase:
Str::camel('host_name');    // 'hostName'
Str::camel('display-name'); // 'displayName'

// Split on a delimiter and trim whitespace from every part in one pass:
Str::trimSplit(' foo , bar , baz '); // ['foo', 'bar', 'baz']
Str::trimSplit('root:secret', ':');  // ['root', 'secret']

// Always return exactly $limit parts: pads with null if the delimiter is
// absent, and fold any remainder into the last part if there are more
// separators than expected:
[$user, $pass] = Str::symmetricSplit('root', ':', 2);              // ['root', null]
[$user, $pass] = Str::symmetricSplit('root:secret:extra', ':', 2); // ['root', 'secret:extra']

// Case-insensitive prefix check:
Str::startsWith('Foobar', 'foo', caseSensitive: false); // true
Str::startsWith('foobar', 'foo');                       // true
```

### Seq

[](#seq)

`Seq` searches arrays, iterators, and generators by value, key, or callback without first materializing them into arrays. When the second argument to `find` or `contains` is a non-callable, it is compared by value; pass a closure to match by predicate instead:

```
use ipl\Stdlib\Seq;

$users = [
    'alice' => 'admin',
    'bob'   => 'viewer',
];

Seq::contains($users, 'viewer'); // true

[$key, $value] = Seq::find($users, 'admin'); // ['alice', 'admin']

// Match by predicate — returns as soon as a result is found:
[$key, $value] = Seq::find($users, fn(string $role): bool => $role !== 'admin'); // ['bob', 'viewer']
```

### Iterable Helpers

[](#iterable-helpers)

```
use function ipl\Stdlib\iterable_key_first;
use function ipl\Stdlib\iterable_value_first;

$map = [
    'id'   => 42,
    'name' => 'Alice',
];

iterable_key_first($map);   // 'id'
iterable_value_first($map); // 42

// Works with generators and iterators — does not require an array:
iterable_key_first(new ArrayIterator(['a' => 1])); // 'a'
iterable_key_first([]);                            // null
```

### Grouping With `yield_groups`

[](#grouping-with-yield_groups)

`yield_groups` partitions a pre-sorted traversable into named groups. The callback must return at least the grouping criterion, but it can also return a custom value and key. The traversable **must** be sorted by the grouping criterion before being passed in; results are undefined otherwise:

```
use function ipl\Stdlib\yield_groups;

foreach (yield_groups($rows, fn(object $row): string => $row->category) as $category => $items) {
    // $items contains all rows for $category.
}
```

### Other Utility Classes

[](#other-utility-classes)

- `Data` — mutable key/value store
- `Messages` — collects user-facing messages and supports `sprintf`-style placeholders
- `PriorityQueue` — extends `SplPriorityQueue` with stable insertion-order for items at equal priority; iterate non-destructively with `yieldAll()`

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for a list of notable changes.

License
-------

[](#license)

`ipl/stdlib` is licensed under the terms of the [MIT License](LICENSE.md).

###  Health Score

61

—

FairBetter than 98% of packages

Maintenance97

Actively maintained with recent releases

Popularity33

Limited adoption so far

Community32

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

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

Recently: every ~200 days

Total

19

Last Release

2d ago

PHP version history (5 changes)v0.2.0PHP &gt;=5.4.0

v0.5.0PHP &gt;=5.6.0

v0.11.0PHP &gt;=7.0

v0.12.0PHP &gt;=7.2

v0.15.0.x-devPHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/39625a91c802211110651e31881abdd47b715dad6a8879493d55933eb24a46c0?d=identicon)[ipl](/maintainers/ipl)

---

Top Contributors

[![lippserd](https://avatars.githubusercontent.com/u/1894563?v=4)](https://github.com/lippserd "lippserd (94 commits)")[![nilmerg](https://avatars.githubusercontent.com/u/16668527?v=4)](https://github.com/nilmerg "nilmerg (66 commits)")[![Thomas-Gelf](https://avatars.githubusercontent.com/u/553008?v=4)](https://github.com/Thomas-Gelf "Thomas-Gelf (15 commits)")[![sukhwinder33445](https://avatars.githubusercontent.com/u/54990055?v=4)](https://github.com/sukhwinder33445 "sukhwinder33445 (10 commits)")[![Jan-Schuppik](https://avatars.githubusercontent.com/u/114286749?v=4)](https://github.com/Jan-Schuppik "Jan-Schuppik (9 commits)")[![yhabteab](https://avatars.githubusercontent.com/u/57616252?v=4)](https://github.com/yhabteab "yhabteab (7 commits)")[![raviks789](https://avatars.githubusercontent.com/u/33730024?v=4)](https://github.com/raviks789 "raviks789 (3 commits)")[![jrauh01](https://avatars.githubusercontent.com/u/81301701?v=4)](https://github.com/jrauh01 "jrauh01 (2 commits)")[![BastianLedererIcinga](https://avatars.githubusercontent.com/u/235492483?v=4)](https://github.com/BastianLedererIcinga "BastianLedererIcinga (1 commits)")

### Embed Badge

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

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

###  Alternatives

[ccxt/ccxt

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

43.2k341.0k1](/packages/ccxt-ccxt)[react/stream

Event-driven readable and writable streams for non-blocking I/O in ReactPHP

691146.0M211](/packages/react-stream)[react/child-process

Event-driven library for executing child processes with ReactPHP.

34691.0M159](/packages/react-child-process)[alchemy/binary-driver

A set of tools to build binary drivers

19511.1M40](/packages/alchemy-binary-driver)[react/zmq

ZeroMQ bindings for React.

2471.7M33](/packages/react-zmq)[mkraemer/react-pcntl

PCNTL bindings for ReactPHP

57290.7k9](/packages/mkraemer-react-pcntl)

PHPackages © 2026

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