Search by

inanepain / stdlib

inanepain

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

Package info

github.com/inanepain/stdlib

Homepage

Issues

pkg:composer/inanepain/stdlib

Statistics

Installs: 114

Dependents: 20

Suggesters: 0

Stars: 1

0.10.0 2026-09-07 18:42 UTC

This package is auto-updated.

Last update: 2026-09-08 20:54:02 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. Enum Bitmask

This section documents the BitmaskEnumTrait used to add bitmask (flags) behaviour to backed `enum`s.

2.1. Overview

BitmaskEnumTrait provides a concise API for working with integer bitmasks on PHP 8.5+ backed enums. It enables:

  • Combining multiple enum cases into a single integer mask

  • Checking if any or all cases are set in a mask

  • Testing for and modifying individual flags (both statically and via instance helpers)

  • Listing the set enum cases from a mask

Trait location:

  • Namespace: Inane\Stdlib\Bitmask

  • File: lib/inanepain/stdlib/src/Bitmask/EnumBitmaskTrait.php

2.2. Requirements and conventions

  • Use on backed enums with int values only.

  • Each enum case should represent a single bit: use powers of two (e.g. 1 << 0, 1 << 1, 1 << 2, …).

  • Masks are plain integers (int).

2.3. API

Static helpers on the enum using the trait:

  • parseBitmask(mixed $mask): int — Normalises arbitrary input into an int mask (null-safe, defaults to 0).

  • combine(self …​$flags): int — ORs cases to a single mask.

  • hasAny(int $mask): bool — True if any defined case is present in the mask.

  • hasAll(int $mask): bool — True if all defined cases are present in the mask.

  • has(int $mask, self $flag): bool — True if the given case is present in the mask.

  • add(int $mask, self $flag): int — Returns a mask with the case added.

  • remove(int $mask, self $flag): int — Returns a mask with the case removed.

  • list(int $mask): array<self> — Returns the enum cases present in the mask.

Instance helpers in an enum case:

  • in(int $mask): bool — True if this case is present in the mask.

  • addTo(int $mask): int — Returns a mask with this case added.

  • removeFrom(int $mask): int — Returns a mask with this case removed.

Note Internally, hasAny and hasAll use array helpers equivalent to “any”/“all” checks over self::cases().

2.4. Example: Permission flags

The following example shows a typical permission enum using the trait.

Example: Permissions
<?php
declare(strict_types=1);

use Inane\Stdlib\Bitmask\BitmaskEnumTrait;

enum Permission: int {
    use BitmaskEnumTrait;

    case Read    = 1 << 0; // 1
    case Write   = 1 << 1; // 2
    case Execute = 1 << 2; // 4
    case Delete  = 1 << 3; // 8
}

// Build a mask from multiple flags
$mask = Permission::combine(Permission::Read, Permission::Write); // 3

// Normalise input
$mask = Permission::parseBitmask($mask); // still 3

// Check across the enum
$hasAny = Permission::hasAny($mask); // true (at least one flag set)
$hasAll = Permission::hasAll($mask); // false (not all flags set)

// Check a specific flag
$canRead  = Permission::has($mask, Permission::Read); // true
$canExec  = Permission::has($mask, Permission::Execute); // false

// The same checks via instance helpers
$canRead2 = Permission::Read->in($mask); // true
$canExec2 = Permission::Execute->in($mask); // false

// Modify mask
$mask = Permission::add($mask, Permission::Delete);        // add Delete
$mask = Permission::Write->removeFrom($mask);               // remove Write

// List set flags
$set = Permission::list($mask); // [Permission::Read, Permission::Delete]

2.5. Tips

  • When defining new flags, always shift from 0 upwards (1 << n) and avoid overlapping values.

  • Store masks as integers in persistence layers. The trait makes converting to/from cases trivial.

3. 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.

3.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).

  • ArrayStringShortSyntaxOutput — converts input to a PHP short array syntax string.

  • 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.

3.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.

3.3. Usage

3.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].

3.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"}

3.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";}

3.3.4. ArrayStringShortSyntaxOutput

Converts input data into a PHP short array syntax string ([]). It first uses ArrayOutput to normalise input into an array, then transforms the result to short syntax.

use Inane\Stdlib\Output\ArrayStringShortSyntaxOutput;

$data = ['name' => 'Ada', 'count' => 2];
$output = new ArrayStringShortSyntaxOutput($data);
echo $output->output();
/*
[
  'name' => 'Ada',
  'count' => 2,
]
*/

3.3.5. XmlOutput

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

use Inane\Stdlib\Output\XmlOutput;

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

3.3.6. 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>
*/

3.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(mixed $inputData = null): string {
        // Store input and clear cache if required.
        $this->setInputData($inputData);

        if (!isset($this->outputData)) {
            // ... custom conversion logic ...
            // Store output in cache.
            $this->outputData = "processed data";
        }
        return $this->outputData;
    }
}

3.5. Example

A more complete example, using an Output class as a property.

$opt = new \Inane\Stdlib\Options([
    'one' => $data,
    'two' => [
        'two' => 2,
        'three' => [
            'four' => 'five',
        ],
    ],
]);

final class SomeThing {
    /**
     * Handles the output data and processes it appropriately.
     *
     * @param mixed $outputHandler The handler responsible for managing and processing the output.
     *
     * @return void
     *
     * @throws \RuntimeException If the output handler encounters a processing error.
     */
    private \Inane\Stdlib\Output\OutputInterface $outputHandler;

    /**
     * Initializes the class with the given input data.
     *
     * @param mixed $inputData The data to be processed by the class.
     *
     * @return void
     *
     * @throws \InvalidArgumentException If the input data is invalid.
     */
    public function __construct(protected mixed $inputData) {}

    /**
     * Sets the output handler to be used.
     *
     * @param \Inane\Stdlib\Output\OutputInterface $outputHandler The output handler to set.
     *
     * @return void
     *
     * @throws \InvalidArgumentException If the provided output handler is invalid.
     */
    public function setOutput(\Inane\Stdlib\Output\OutputInterface $outputHandler): void {
        $this->outputHandler = $outputHandler;
    }

    /**
     * Processes the input data and returns the output.
     *
     * @return mixed The result of processing the input data.
     *
     * @throws \Exception If an error occurs during output processing.
     */
    public function output(): mixed {
        return $this->outputHandler->output($this->inputData);
    }
}


echo "\nREUSABLE:\n";
$thing = new SomeThing($opt);
$thing->setOutputHandler(new \Inane\Stdlib\Output\XmlStringOutput());
echo "\nXMLString:\n";
var_dump($thing->output());

$thing->setOutputHandler(new \Inane\Stdlib\Output\XmlOutput());
echo "\nXML:\n";
var_dump($thing->output());

$thing->setOutputHandler(new \Inane\Stdlib\Output\ArrayOutput());
echo "\nARRAY:\n";
var_dump($thing->output());

$thing->setOutputHandler(new \Inane\Stdlib\Output\JsonStringOutput());
echo "\nJSON:\n";
var_dump($thing->output());

4. 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

4.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.

4.2. Strategies (MergeMethod)

MergeMethod controls how keys are handled during a merge:

  • AddOnly — only add keys that don’t 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.

4.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

4.4. Usage

4.4.1. Static helpers

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
```

=== Instance with a configurable method

```php
<?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 ]

4.5. Behaviour 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.

4.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.

4.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;

4.8. JavaScript counterpart

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

4.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.

5. Value

Classes that verify or sanitise values. Mostly using filter_var.

5.1. Verify Value

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.

5.1.1. Methods

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
alphaVerify

Validates an alphabetic string.

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

$value

string

The value to validate.

Example
VerifyValue::alphaVerify('Hello');     // 'Hello'
VerifyValue::alphaVerify('Hello123');  // false
digitVerify

Validates a value containing only decimal digits.

Signature
public static function digitVerify(mixed $value): mixed
Table 3. Parameters
Parameter Type Description

$value

mixed

The value to validate.

Example
VerifyValue::digitVerify('12345');  // '12345'
VerifyValue::digitVerify('12.45');  // false
xdigitVerify

Validates a value containing only hexadecimal digits.

Signature
public static function xdigitVerify(mixed $value): mixed
Table 4. Parameters
Parameter Type Description

$value

mixed

The value to validate.

Example
VerifyValue::xdigitVerify('1A2b3C');  // '1A2b3C'
VerifyValue::xdigitVerify('0x1A');    // false
alphaNumericVerify

Validates an alphanumeric string.

Signature
public static function alphaNumericVerify(string $value): false|string
Table 5. Parameters
Parameter Type Description

$value

string

The value to validate.

Example
VerifyValue::alphaNumericVerify('abc123');   // 'abc123'
VerifyValue::alphaNumericVerify('abc 123');  // false
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 6. 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']
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 7. 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
intVerify

Validates an integer value using an option 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 8. 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
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 9. 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
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 10. 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
domainVerify

Validates a domain name, optionally enforcing strict hostname rules.

Signature
public static function domainVerify(mixed $value, bool $hostname = false): ?string
Table 11. 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
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 12. 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
macVerify

Validates a MAC address and optionally normalises its format.

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

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

$value

mixed

The value to validate as a MAC address.

$normalise

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.2. Sanitise Value

Utility class providing static methods for sanitising common value types such as strings containing markup, emails, URLs, integers and floats.

Most methods wrap PHP’s native filter_var function with a consistent, expressive API and sensible defaults. Each method accepts either a single value or an array of values.

5.2.1. Methods

stripTags

Removes HTML and PHP tags from a string or each string in an array.

Signature
public static function stripTags(string|array $string, array|string|null $allowedTags = null): string|array
Table 14. Parameters
Parameter Type Description

$string

string|array

The value to sanitise.

$allowedTags

array|string|null

Tags permitted in the result.

Example
SanitiseValue::stripTags('<p>Hello <b>World</b></p>');            // 'Hello World'
SanitiseValue::stripTags('<p>Hello <b>World</b></p>', '<b>');     // 'Hello <b>World</b>'
SanitiseValue::stripTags(['<i>a</i>', '<i>b</i>']);               // ['a', 'b']
emailSanitise

Sanitises an email address or each address in an array.

Signature
public static function emailSanitise(string|array $value, bool $stripTags = false): false|string|array
Table 15. Parameters
Parameter Type Description

$value

string|array

The email address or addresses to sanitise.

$stripTags

bool

Whether to remove tags before sanitising.

Example
SanitiseValue::emailSanitise('us(er)@example.com');                  // 'user@example.com'
SanitiseValue::emailSanitise('<b>user</b>@example.com', true);       // 'user@example.com'
SanitiseValue::emailSanitise(['a b@c.com', 'd@e.com']);              // ['ab@c.com', 'd@e.com']
urlSanitise

Sanitises a URL or each URL in an array.

Signature
public static function urlSanitise(string|array $value, bool $stripTags = false): false|string|array
Table 16. Parameters
Parameter Type Description

$value

string|array

The URL or URLs to sanitise.

$stripTags

bool

Whether to remove tags before sanitising.

Example
SanitiseValue::urlSanitise('http://exa mple.com/pa th');           // 'http://example.com/path'
SanitiseValue::urlSanitise('<b>http://example.com</b>', true);     // 'http://example.com'
intSanitise

Sanitises an integer value or each value in an array by removing all characters except digits, plus and minus signs.

Signature
public static function intSanitise(int|float|string|array $value): false|int|array
Table 17. Parameters
Parameter Type Description

$value

int|float|string|array

The value or values to sanitise.

Example
SanitiseValue::intSanitise('R 1 234.56');          // '123456'
SanitiseValue::intSanitise('-42abc');              // '-42'
SanitiseValue::intSanitise(['1a', '2b']);          // ['1', '2']
floatSanitise

Sanitises a floating-point value or each value in an array.

By default, all characters except digits, plus and minus signs are removed. The optional flags retain decimal separators, thousand separators and scientific notation respectively.

Signature
public static function floatSanitise(int|float|string|array $value, bool $allowFraction = false, bool $allowThousand = false, bool $allowScientific = false): false|float|array
Table 18. Parameters
Parameter Type Description

$value

int|float|string|array

The value or values to sanitise.

$allowFraction

bool

Whether to retain decimal separators.

$allowThousand

bool

Whether to retain thousand separators.

$allowScientific

bool

Whether to retain scientific notation.

Example
SanitiseValue::floatSanitise('R 1,234.56');                       // '123456'
SanitiseValue::floatSanitise('R 1,234.56', true);                 // '1234.56'
SanitiseValue::floatSanitise('R 1,234.56', true, true);           // '1,234.56'
SanitiseValue::floatSanitise('1.2e3', true, false, true);         // '1.2e3'

6. FuzzyTime

This section documents the FuzzyTimeTrait used to express a point in time the way a person would say it out loud.

6.1. Overview

FuzzyTimeTrait converts a time into a spoken-style English phrase such as quarter past nine. It provides:

  • Rounding of minutes to the nearest five minutes

  • past phrasing up to and including half past the hour

  • to phrasing with the following hour after half past

  • Hour roll-over when the rounded minutes reach sixty

Trait location:

  • Namespace: Inane\Stdlib\Parser

  • File: lib/inanepain/stdlib/src/Parser/FuzzyTimeTrait.php

6.2. Requirements and conventions

  • Use on any class that needs fuzzy time wording; the API is static, so no state is added.

  • Accepted input is a DateTime, an Inane\Datetime\Timestamp, or null for the current time.

  • Output is a twelve-hour phrase without a meridiem indicator: one o’clock covers both 01:00 and 13:00.

6.3. API

Static helper on the class using the trait:

  • fuzzyClock(null|\DateTime|Timestamp $time = null): string — Returns the time in words, defaulting to now.

Note numToWords() it’s an internal helper and isn’t part of the public API.

6.4. Example: Time in words

<?php
declare(strict_types=1);

use Inane\Stdlib\Parser\FuzzyTimeTrait;

final class Clock {
    use FuzzyTimeTrait;
}

// Exact hour
Clock::fuzzyClock(new DateTime('2026-07-04 13:00:00')); // one o'clock

// Minutes rounded to the nearest five, phrased as past
Clock::fuzzyClock(new DateTime('2026-07-04 09:13:00')); // quarter past nine

// After half past, phrased as to the next hour
Clock::fuzzyClock(new DateTime('2026-07-04 09:34:00')); // twenty-five to ten

// Rounding up to sixty minutes rolls the hour over
Clock::fuzzyClock(new DateTime('2026-07-04 23:58:00')); // twelve o'clock

// Current time
Clock::fuzzyClock();

6.5. Tips

  • Set the timezone on the supplied DateTime; the wording follows whatever local time the object reports.

  • Because the phrasing is rounded, it suits summaries and labels rather than anything needing exact times.

7. ClassUtility

This section documents ClassUtility, a small helper for working out class information without loading the class.

7.1. Overview

ClassUtility inspects PHP source with the tokeniser, so a file can be examined without being included. It provides:

  • Extraction of the fully qualified class name declared in a file

  • A class id helper, courtesy of ClassIdTrait

Class location:

  • Namespace: Inane\Stdlib\Utility

  • File: lib/inanepain/stdlib/src/Utility/ClassUtility.php

7.2. Requirements and conventions

  • The API is static; there’s no need to create an instance.

  • A file may be given as a path string or an Inane\File\File instance.

  • Only the first class declared in a file is reported, which suits PSR-4 style one-class-per-file layouts.

  • An invalid or missing file raises Inane\Stdlib\Exception\Exception.

7.3. API

  • getClassFromFile(string|File $file): ?string — Returns the fully qualified class name declared in the file, or null when the file declares no class.

  • classId(int $size = 0, string $separator = '/', bool $lower = true, ?string $className = null): string — From ClassIdTrait, builds an id from the class name.

7.4. Example: Class name from a file

<?php
declare(strict_types=1);

use Inane\File\File;
use Inane\Stdlib\Utility\ClassUtility;

// A namespaced class returns the fully qualified name
ClassUtility::getClassFromFile('src/Utility/ClassUtility.php'); // Inane\Stdlib\Utility\ClassUtility

// A `File` instance works just as well
ClassUtility::getClassFromFile(new File('src/Utility/ClassUtility.php')); // Inane\Stdlib\Utility\ClassUtility

// Without a namespace, only the class name comes back
ClassUtility::getClassFromFile('legacy/Gamma.php'); // Gamma

// A file with no class declaration
ClassUtility::getClassFromFile('config/settings.php'); // null

7.5. Example: Class id

<?php
declare(strict_types=1);

use Inane\Stdlib\Utility\ClassUtility;

ClassUtility::classId(1); // classutility
ClassUtility::classId(2, '/', false); // Utility/ClassUtility

7.6. Tips

  • Handy when scanning a directory to map files to classes, for example, when building a plugin or module registry.

  • Because it reads a source rather than reflecting, it’s safe to use on files you don’t wish to execute.

  • Wrap calls in a try/catch when scanning paths that may not exist.

8. Website: github

github

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