inanepain/stdlib

Common classes that cover a wide range of cases that are used throughout the inanepain libraries.

Maintainers

Package info

github.com/inanepain/stdlib

Homepage

Issues

pkg:composer/inanepain/stdlib

Statistics

Installs: 112

Dependents: 20

Suggesters: 0

Stars: 1

0.8.0 2026-02-23 18:14 UTC

This package is auto-updated.

Last update: 2026-05-22 22:55:54 UTC


README

Table of Contents

icon inanepain/stdlib

Common classes that cover a wide range of cases that are used throughout the inanepain libraries.

1. Install

composer
composer require inanepain/stdlib

2. Output Strategy

The Output component provides a consistent strategy for converting data into various formats. It is designed around the OutputInterface and an abstract base class, allowing for easy expansion and uniform usage across the framework.

The Output tools are located in the Inane\Stdlib\Output namespace.

2.1. Components

  • OutputInterface — defines the output() method.

  • AbstractOutput — base implementation handling input data storage and lazy-processing.

  • ArrayOutput — converts input to a PHP array (supports JSON, Serialized, Objects).

  • JsonStringOutput — converts input to a JSON string.

  • SerializedOutput — converts input to a PHP serialized string.

  • XmlOutput — converts input to a SimpleXMLElement object.

  • XmlStringOutput — converts input to an XML string.

2.2. API Overview

All output classes share the same constructor and method:

public function __construct(protected mixed $inputData);

public function output(): mixed;

The output() method is lazy-loaded; the processing happens once and the result is cached in the outputData property.

2.3. Usage

2.3.1. ArrayOutput

ArrayOutput is highly flexible. It attempts to detect the input type and convert it to an array accordingly.

use Inane\Stdlib\Output\ArrayOutput;

// From an object (recursive conversion)
$output = new ArrayOutput($myObject);
$array = $output->output();

// From a JSON string
$output = new ArrayOutput('{"key": "value"}');
$array = $output->output(); // ['key' => 'value']

// From a serialized string
$output = new ArrayOutput(serialize(['a' => 1]));
$array = $output->output(); // ['a' => 1]
Conversion Logic (ArrayOutput)
  1. If input is an array, it is returned as is.

  2. If input is a string:

    • Tries to decode as JSON.

    • If not JSON, tries to unserialize.

    • If both fail, wraps the string in an array: [$input].

  3. If input is an object, it uses iteratorToArrayDeep to convert it recursively.

  4. For any other type, it wraps the input in an array: [$input].

2.3.2. JsonStringOutput

Converts any input into a JSON string using Inane\Stdlib\Json.

use Inane\Stdlib\Output\JsonStringOutput;

$data = ['name' => 'Inane', 'type' => 'Framework'];
$output = new JsonStringOutput($data);
echo $output->output(); // {"name":"Inane","type":"Framework"}

2.3.3. SerializedOutput

Converts input into a PHP serialized string.

use Inane\Stdlib\Output\SerializedOutput;

$output = new SerializedOutput(['a', 'b', 'c']);
echo $output->output(); // a:3:{i:0;s:1:"a";i:1;s:1:"b";i:2;s:1:"c";}

2.3.4. XmlOutput

Converts input data into a SimpleXMLElement. It uses ArrayOutput internally to normalize the input before conversion.

use Inane\Stdlib\Output\XmlOutput;

$data = ['user' => ['id' => 1, 'name' => 'John']];
$output = new XmlOutput($data);
$xml = $output->output(); // SimpleXMLElement instance

2.3.5. XmlStringOutput

Converts input data into a formatted XML string.

use Inane\Stdlib\Output\XmlStringOutput;

$data = ['root' => ['item' => 'value']];
$output = new XmlStringOutput($data);
echo $output->output();
/*
<?xml version="1.0"?>
<data><root><item>value</item></root></data>
*/

2.4. Extending

To create a new output format, extend AbstractOutput and implement the output() method:

use Inane\Stdlib\Output\AbstractOutput;

class MyCustomOutput extends AbstractOutput {
    public function output(): string {
        if (!isset($this->outputData)) {
            // ... custom conversion logic ...
            $this->outputData = "processed data";
        }
        return $this->outputData;
    }
}

3. Merge

Helper utilities for merging configuration/options arrays and iterators with explicit control over how keys are added and/or updated. The Merge tool lives under Inane\Stdlib\Merge and consists of:

  • MergeTrait — core implementation and convenience helpers

  • Merge — small class that exposes the trait as a ready‑to‑use type

  • MergeInterface — contract for merge behaviour

  • MergeMethod — enum that selects the merge strategy

3.1. When to use

Use Merge to combine option sets coming from defaults, environment, per‑user overrides, feature flags, etc. It supports nested structures and works with both PHP arrays and ArrayAccess/Iterator implementations.

3.2. Strategies (MergeMethod)

MergeMethod controls how keys are handled during a merge:

  • AddOnly — only add keys that do not exist on the target; existing keys are left unchanged.

  • UpdateOnly (default) — only update keys that already exist on the target; new keys are ignored.

  • AddAndUpdate — add missing keys and update existing keys (full overlay/recursive replace).

Merging is recursive for nested arrays/objects that are arrays or implement ArrayAccess/Iterator on both source and target sides.

3.3. API overview

Namespace: Inane\Stdlib\Merge

Core static method:

Iterator|array MergeTrait::mergeOptionsWithMethod(
    MergeMethod $mergeMethod,
    Iterator|array $target,
    Iterator|array ...$sources
): Iterator|array

Convenience helpers (static):

  • mergeOptionsWithAddOnly($target, …​$sources)

  • mergeOptionsWithUpdateOnly($target, …​$sources)

  • mergeOptionsWithAddAndUpdate($target, …​$sources)

Instance method (via Merge or any class using the trait):

public MergeMethod $mergeMethod = MergeMethod::UpdateOnly; // default

public function mergeOptions(Iterator|array $target, Iterator|array ...$sources): Iterator|array

3.4. Usage

3.4.1. Static helpers

<?php
use Inane\Stdlib\Merge\MergeTrait; // used via Merge facade below
use Inane\Stdlib\Merge\Merge;

$defaults = [
    'host' => 'localhost',
    'port' => 3306,
    'flags' => [ 'compress' => false, 'strict' => true ],
];

$env = [
    'port' => 3307,
    'flags' => [ 'compress' => true ],
    'extra' => 'ignored in UpdateOnly',
];

// Update existing keys only (default semantics)
$merged = Merge::mergeOptionsUpdateOnly($defaults, $env);
/* Result:
[
  'host' => 'localhost',
  'port' => 3307,
  'flags' => [ 'compress' => true, 'strict' => true ],
]
*/

// Add missing keys only
$added = Merge::mergeOptionsAddOnly($defaults, ['timeout' => 5]);
// 'timeout' is appended, existing values untouched

// Add and update (full overlay)
$overlay = Merge::mergeOptionsAddAndUpdate($defaults, $env);
// Includes 'extra' and applies nested updates

3.4.2. Instance with a configurable method

<?php
use Inane\Stdlib\Merge\{Merge, MergeMethod};

$merger = new Merge();
$merger->mergeMethod = MergeMethod::AddAndUpdate; // choose strategy at runtime

$target = [ 'a' => 1, 'b' => ['x' => true] ];
$source = [ 'b' => ['x' => false, 'y' => 2], 'c' => 3 ];

$result = $merger->mergeOptions($target, $source);
// [ 'a' => 1, 'b' => ['x' => false, 'y' => 2], 'c' => 3 ]

3.5. Behavior details

  • The key existence on the target is determined as follows:

  • arrays: array_key_exists($key, $target)

  • ArrayAccess: $target→offsetExists($key)

  • iterables: isset($target[$key])

  • Recursion happens only when both source and target values at a key are array‑like (is_array or ArrayAccess). Otherwise, the source value replaces the target value subject to the chosen strategy.

  • Multiple sources are merged left‑to‑right in the order provided.

3.6. Working with iterators and ArrayAccess

You can pass objects implementing Iterator and/or ArrayAccess as both target and sources. Merge will respect their semantics for key existence checks and assignments, allowing use with custom option containers.

3.7. Selecting a strategy dynamically

If you receive a user‑provided string (e.g. from config), you can map it to a MergeMethod case using MergeMethod::tryFromName($name, $ignoreCase = false).

use Inane\Stdlib\Merge\MergeMethod;

$method = MergeMethod::tryFromName('addonly', true) ?? MergeMethod::UpdateOnly;

3.8. JavaScript counterpart

For frontend experiments there is a simple ES module at public/js/inane/class-lib/MergeOptions.mjs that mirrors the basic behaviour for merging option objects.

3.9. Tips

  • Use UpdateOnly to enforce a strict schema: only predefined keys get updated.

  • Use AddOnly to apply safe defaults without overwriting user choices.

  • Use AddAndUpdate when you want a typical deep overlay of configuration.

4. VerifyValue

Utility class providing static methods for validating and verifying common value types such as booleans, emails, integers, floats, IP addresses, MAC addresses, domains, and regex-matched strings.

All methods wrap PHP’s native filter_var function with a consistent, expressive API and sensible defaults.

4.1. Methods

4.1.1. boolVerify

Validates and converts a given value into a boolean.

Accepts the same truthy/falsy strings that PHP’s filter_var recognises (e.g. "true", "yes", "1", "on" and their negatives).

Signature
public static function boolVerify(mixed $value, bool $nullOnFailure = false): ?bool
Table 1. Parameters
Parameter Type Description

$value

mixed

The value to validate and convert to boolean.

$nullOnFailure

bool

When true, returns null on failure instead of false.

Example
VerifyValue::boolVerify('yes');          // true
VerifyValue::boolVerify('off');          // false
VerifyValue::boolVerify('maybe', true);  // null

4.1.2. emailVerify

Validates an email address or an array of email addresses.

When an array is supplied, each element is validated individually, and the method returns an associative array keyed by the original input values.

Signature
public static function emailVerify(string|array $value): false|string|array
Table 2. Parameters
Parameter Type Description

$value

string|array

A single email address string, or an array of email address strings.

Example
VerifyValue::emailVerify('user@example.com');                    // 'user@example.com'
VerifyValue::emailVerify('not-an-email');                        // false
VerifyValue::emailVerify(['a@b.com', 'bad', 'c@d.com']);        // ['a@b.com' => 'a@b.com', 'bad' => false, 'c@d.com' => 'c@d.com']

4.1.3. integerVerify

Validates an integer value with optional range and base constraints.

Supports octal (prefix 0) and hexadecimal (prefix 0x) notation when the corresponding flags are enabled.

Signature
public static function integerVerify(mixed $int, mixed $default = false, ?int $min = null, ?int $max = null, bool $allowOctal = false, bool $allowHex = false): bool
Table 3. Parameters
Parameter Type Description

$int

mixed

The value to validate as an integer.

$default

mixed

Fallback value returned on validation failure. Pass false to omit.

$min

int|null

Optional minimum allowed value (inclusive).

$max

int|null

Optional maximum allowed value (inclusive).

$allowOctal

bool

When true, octal notation is accepted.

$allowHex

bool

When true, hexadecimal notation is accepted.

Example
VerifyValue::integerVerify(42);                        // true
VerifyValue::integerVerify(42, false, 1, 100);         // true
VerifyValue::integerVerify(200, false, 1, 100);        // false
VerifyValue::integerVerify('0x1A', false, null, null, false, true);  // true

4.1.4. intVerify

Validates an integer value using a named options array.

A convenience wrapper around integerVerify() that accepts a named options array instead of individual parameters. Unrecognised keys are silently ignored.

Signature
public static function intVerify(mixed $int, array $options = []): bool
Table 4. Parameters
Parameter Type Description

$int

mixed

The value to validate as an integer.

$options

array

Named validation options: default, min, max, allowOctal, allowHex.

Example
VerifyValue::intVerify(42, ['min' => 1, 'max' => 100]);   // true
VerifyValue::intVerify('0xFF', ['allowHex' => true]);      // true

4.1.5. floatVerify

Validates a float value with optional range and thousand-separator support.

Signature
public static function floatVerify(mixed $int, mixed $default = false, ?int $min = null, ?int $max = null, bool $acceptFloat = false): bool
Table 5. Parameters
Parameter Type Description

$int

mixed

The value to validate as a float.

$default

mixed

Fallback value returned on validation failure. Pass false to omit.

$min

int|null

Optional minimum allowed value (inclusive).

$max

int|null

Optional maximum allowed value (inclusive).

$acceptFloat

bool

When true, values containing a thousand separator (,) are accepted.

Example
VerifyValue::floatVerify(3.14);                        // true
VerifyValue::floatVerify('1,234.56', false, null, null, true);  // true
VerifyValue::floatVerify('abc');                       // false

4.1.6. regexVerify

Validates a value against a regular expression pattern.

Returns the original value when it matches the pattern, the $default string when provided and the match fails, or null otherwise.

Signature
public static function regexVerify(mixed $value, string $pattern, ?string $default = null): ?string
Table 6. Parameters
Parameter Type Description

$value

mixed

The value to validate.

$pattern

string

A valid PCRE regular expression (including delimiters).

$default

string|null

Optional fallback string returned when validation fails.

Example
VerifyValue::regexVerify('hello123', '/^[a-z]+\d+$/');          // 'hello123'
VerifyValue::regexVerify('!!!', '/^[a-z]+$/', 'no-match');      // 'no-match'
VerifyValue::regexVerify('!!!', '/^[a-z]+$/');                  // null

4.1.7. domainVerify

Validates a domain name, optionally enforcing strict hostname rules.

Signature
public static function domainVerify(mixed $value, bool $hostname = false): ?string
Table 7. Parameters
Parameter Type Description

$value

mixed

The value to validate as a domain name.

$hostname

bool

When true, applies stricter hostname validation rules.

Example
VerifyValue::domainVerify('example.com');          // 'example.com'
VerifyValue::domainVerify('-bad.com', true);       // null
VerifyValue::domainVerify('not a domain');         // null

4.1.8. ipVerify

Validates an IP address with configurable version and range policies.

By default, both IPv4 and IPv6 addresses are accepted. Passing false for one version while leaving the other as true restricts validation to the remaining version.

Signature
public static function ipVerify(mixed $value, bool $allowV4 = true, bool $allowV6 = true, bool $denyPrivate = false, bool $denyReserved = false, bool $globalOnly = false): ?string
Table 8. Parameters
Parameter Type Description

$value

mixed

The value to validate as an IP address.

$allowV4

bool

Accept IPv4 addresses (default true).

$allowV6

bool

Accept IPv6 addresses (default true).

$denyPrivate

bool

Reject private-range addresses (e.g. 192.168.x.x).

$denyReserved

bool

Reject reserved-range addresses (e.g. 0.0.0.0).

$globalOnly

bool

Accept only globally routable addresses.

Example
VerifyValue::ipVerify('192.168.1.1');                          // '192.168.1.1'
VerifyValue::ipVerify('192.168.1.1', true, true, true);       // null (private range denied)
VerifyValue::ipVerify('::1', false, true);                    // '::1' (IPv6 only)
VerifyValue::ipVerify('not-an-ip');                           // null

4.1.9. macVerify

Validates a MAC address and optionally normalises its format.

PHP’s filter_var accepts colons (:), hyphens (-), and dots (.) as separators. When $normalize is true the validated address is stripped of its original separators and rebuilt using $separator.

Signature
public static function macVerify(mixed $value, bool $normalize = false, string $separator = ':'): ?string
Table 9. Parameters
Parameter Type Description

$value

mixed

The value to validate as a MAC address.

$normalize

bool

When true, the returned address is normalised to a consistent separator.

$separator

string

The separator character used when normalising (default :).

Example
VerifyValue::macVerify('00-1A-2B-3C-4D-5E');                    // '00-1A-2B-3C-4D-5E'
VerifyValue::macVerify('00-1A-2B-3C-4D-5E', true);              // '00:1a:2b:3c:4d:5e'
VerifyValue::macVerify('00.1A.2B.3C.4D.5E', true, '-');         // '00-1a-2b-3c-4d-5e'
VerifyValue::macVerify('not-a-mac');                            // null

5. Website: github

github

  ██████████████    ██████████      ██  ████    ████  ██  ██  ██████████████
  ██          ██      ██  ████          ██████████        ██  ██          ██
  ██  ██████  ██  ████  ████  ████████  ██████████████████    ██  ██████  ██
  ██  ██████  ██  ████        ██      ████    ████████  ████  ██  ██████  ██
  ██  ██████  ██    ██      ██  ████    ██  ██                ██  ██████  ██
  ██          ██    ██        ██████    ██    ██  ██          ██          ██
  ██████████████  ██  ██  ██  ██  ██  ██  ██  ██  ██  ██  ██  ██████████████
                      ██    ██████      ██  ██████████  ████
        ████  ████  ██  ████    ██  ██  ██    ██  ████    ██        ████
  ██    ████      ████      ████  ██  ██        ██  ██      ████  ██
  ████    ██████████            ██      ██    ██  ████      ████████      ██
        ████      ████████    ██    ████      ██      ████  ████    ████  ██
  ██  ████  ████  ████  ██  ████    ██    ██              ██  ████  ██  ████
  ██      ████      ████  ██████  ██        ██    ██  ████  ██    ██  ██
            ████      ██████████████    ██████  ██    ████████  ██  ████████
        ██  ██        ██  ██████  ██      ██  ████      ██        ██████  ██
      ████    ██████  ██  ██  ██    ████    ██  ██████        ██      ██  ██
  ██  ██████          ██        ██████  ████████  ██    ██  ██          ██
  ████  ████████  ████████████    ████████    ██████  ████  ██████  ████  ██
    ██  ██      ██  ████    ████  ████  ██  ████  ████  ██████████████  ██
    ██    ████████                  ██  ██      ██    ██  ██████  ██      ██
  ██  ████████    ██    ██  ██████  ████  ██████  ████  ████    ██████
    ██      ████  ██      ██          ██        ██  ██  ██        ██████  ██
  ██    ██  ██      ████    ██  ██    ████  ██      ██  ██████  ██  ████████
    ██  ██████████    ████  ████  ██████    ██████████          ██████
  ██  ██    ██    ██        ██  ██  ██  ██  ████    ████      ██
  ████  ██  ██████    ████  ██████  ████        ████  ████    ████████  ████
  ██  ██████    ████  ██████    ██████████    ████        ████  ██    ██
  ██  ██████  ████  ██    ████  ██████████████    ████  ██████████████
                  ██████  ████████  ██    ██  ██    ██    ██      ██████
  ██████████████  ██      ██████  ██████  ████  ████████  ██  ██  ██████  ██
  ██          ██    ██████    ████    ██            ██  ████      ████  ████
  ██  ██████  ██  ████  ██  ████  ████  ██    ██      ██████████████
  ██  ██████  ██  ██    ██████    ████  ██        ██  ██████  ████  ████
  ██  ██████  ██    ██      ██████████    ██  ████      ████    ████    ████
  ██          ██          ██    ██  ██  ██      ████        ██████  ████████
  ██████████████      ██    ██    ████      ██  ████      ██      ████    ██