PHPackages                             neunerlei/options - 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. neunerlei/options

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

neunerlei/options
=================

A little helper which can be used to apply a schema to any given array

2.0.0(4y ago)02.0k[1 PRs](https://github.com/Neunerlei/options-php/pulls)1Apache-2.0PHPPHP ^7.3CI failing

Since Mar 1Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/Neunerlei/options-php)[ Packagist](https://packagist.org/packages/neunerlei/options)[ RSS](/packages/neunerlei-options/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (2)Versions (11)Used By (1)

Option Applier
==============

[](#option-applier)

This nifty little helper can be used to apply a schema to any given array. It is designed to work as an on-the-fly validator for method options but is powerful enough to validate all sorts of API requests as well.

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

[](#installation)

Install this package using composer:

```
composer require neunerlei/options

```

Basic Usage
-----------

[](#basic-usage)

The main purpose of the package is to validate options that are passed to methods or functions, like in this basic example:

```
use Neunerlei\Options\Options;
function myFunc(array $options = []){
    // Apply the options
    $options = Options::make($options, [
        "foo" => 123,
        "bar" => null,
    ]);
    print_r($options);
}

myFunc(); // Prints: ["foo" => 123, "bar" => null]
myFunc(["bar" => "baz"]);  // Prints: ["foo" => 123, "bar" => "baz"]
myFunc(["baz" => 234]); // This will cause an exception, because the key "baz" is not known
```

Simple Definition
-----------------

[](#simple-definition)

As you can see above, you can define a simple list of keys and matching default values, that act like "array\_merge" would. All keys passed to $options that are not in the definition will throw a validation exception. In general, you can pass any value as a default (arrays require a little quirk, tho (see below));

#### Defining an array as default value

[](#defining-an-array-as-default-value)

Please note that it is not possible to pass an array as a default value like you would with any other type. You have to make sure that your default array is wrapped by an outer array like:

```
use Neunerlei\Options\Options;
$options = Options::make($options, [
    "foo" => [["my" => "defaultValue"]]
]);
```

If you don't wrap the default array in an array a InvalidOptionDefinitionException will be thrown.

Advanced Definition
-------------------

[](#advanced-definition)

In addition to the simple default values, you can also use an array as a value in your definitions array. In it, you can set the following options to validate and manipulate the options to your liking.

I choose arrays as a definition because they run fast,and one is only required to remember a handful of options.

### Options

[](#options)

#### default *(mixed|callable)*

[](#default-mixedcallable)

This is the default value to use when the key in $options is not given. If not set, the option key is required! If the default value is a Closure, the closure is called, and its result is used as the value.

```
use Neunerlei\Options\Options;

// Simple value default
$options = Options::make($options, [
    "foo" => [
        "default" => 123
    ]
]);

// Closure result value default
$options = Options::make($options, [
    "foo" => [
        "default" => function($key, $options, $node, $context){
            return 123;
        }
    ]
]);
```

#### type *(string|array)*

[](#type-stringarray)

Allows basic type validation of the input. It can either be a string or an array of strings. If multiple values are supplied as an array, they are seen as chained via OR operator. Possible values are:

- boolean
- bool
- true
- false
- integer
- int
- double
- float
- number (int and float)
- numeric (both int and float + string numbers -&gt; is\_numeric)
- string
- resource
- null
- callable

It is also possible to validate the type of an instance based on a class or interface name.

```
use Neunerlei\Options\Options;

// Simple types
$options = Options::make($options, [ "foo" => [ "type" => "string" ] ]);
$options = Options::make($options, [ "foo" => [ "type" => "number" ] ]);
$options = Options::make($options, [ "foo" => [ "type" => [ "number", "string" ] ] ]);

// Class types
interface AI {};
class A implements AI {}
class B extends A {}
$options = Options::make(["foo" => new A()], [ "foo" => [ "type" => [A::class]]]); // OK -> Same class
$options = Options::make(["foo" => new B()], [ "foo" => [ "type" => [A::class]]]); // OK -> A is the parent
$options = Options::make(["foo" => new B()], [ "foo" => [ "type" => [AI::class]]]); // OK -> AI is implemented by the parent
$options = Options::make(["foo" => new A()], [ "foo" => [ "type" => [B::class]]]); // FAIL
```

#### preFilter *(callable)*

[](#prefilter-callable)

A callback that is called **BEFORE** the type validation takes place and can be used to cast the incoming value before validating its type.

```
use Neunerlei\Options\Options;
$options = Options::make($options, [
    "foo" => [
        "preFilter" => function($incomingValue, $key, $options, $node, $context){
            if(is_string($incomingValue)) {return (int)$incomingValue;}
            return $incomingValue;
        }
    ]
]);
```

#### filter *(callable)*

[](#filter-callable)

A callback to call after the type validation took place and can be used to process a given value before the custom validation begins.

```
use Neunerlei\Options\Options;
$options = Options::make($options, [
    "foo" => [
        "type" => "int",
        "filter" => function(int $incomingValue, $key, $options, $node, $context){
            return empty($incomingValue) ? 1 : $incomingValue;
        }
    ]
]);
```

#### validator *(callable)*

[](#validator-callable)

Executes a given callable. The function receives: $value, $key, $options, $node, $context.

- If the function returns `FALSE` the validation is failed.
- If the function returns `TRUE` the validation is passed.
- If the function returns an array of values, the values will be passed on, and handled like an array passed to " validator".
- If the function returns a string, it is considered a custom error message.

```
use Neunerlei\Options\Options;
$options = Options::make($options, [
    "foo" => [
        "type" => "int",
        "validator" => function(int $incomingValue, $key, $options, $node, $context){
            return TRUE; // Success!
            return FALSE; // Failed
            return "Failed to validate something!"; // Failed with custom error message
            return [123, 234]; // Let the "values" validator decide (see: validator (array))
        }
    ]
]);
```

#### validator *(string)*

[](#validator-string)

If the given value is a non-callable string, it will be evaluated as regular expression

```
use Neunerlei\Options\Options;
$options = Options::make($options, [
    "foo" => [
        "type" => "string",
        "validator" => '~^0-9$~'
    ]
]);
```

#### validator *(array)*

[](#validator-array)

A basic validation routine which receives a list of possible values and will check if the given value will match at least one of them (OR operator).

```
use Neunerlei\Options\Options;
$options = Options::make($options, [
    "foo" => [
        "type" => "int",
        "validator" => [123, 234] // Only 123 or 234 are allowed values
    ]
]);
```

#### children *(array)*

[](#children-array)

This can be used to apply nested definitions on option trees. The `children` definition is done exactly the same way as on root level. The children will only be used if the value in $options is an array (or has a default value of an empty array). There are three options on how children will be evaluated:

1. Validating a direct, associative child of a node:

```
use Neunerlei\Options\Options;
$options = Options::make([], [
    "foo" => [
        "type" => "array",
        "default" => [],
        "children" => [
            "childFoo" => 123,
            "KongFoo" => [
                "type" => "string",
                "default" => "foo!"
            ]
        ]
    ]
]);

// $options will look like:
// [
//     "foo" => [
//         "childFoo" => 123,
//         "KongFoo" => "foo!"
//     ]
// ]
```

2. Validating a list of child nodes that have the same structure:

```
use Neunerlei\Options\Options;
$options = [
    "foo" => [
        ["childFoo" => 234],
        ["KongFoo" => "bar :D"]
    ]
];

$options = Options::make($options, [
    "foo" => [
        "type" => "array",
        "default" => [],
        "children" => [
            // This asterisk defines, that the children are repeatable
            "*" => [
                "childFoo" => 123,
                "KongFoo" => [
                    "type" => "string",
                    "default" => "foo!"
                ]
            ]
        ]
    ]
]);

// $options will look like:
// [
//     "foo" => [
//         ["childFoo" => 234, "KongFoo" => "foo!"],
//         ["childFoo" => 123, "KongFoo" => "bar :D"]
//     ]
// ];
```

3. Validating a list of values with the same type, (for example a list of phone numbers):

```
use Neunerlei\Options\Options;
$options = [
    "foo" => [
        'HOW',
        'ARE',
        'YOU'
    ]
];

$options = Options::make($options, [
    "foo" => [
        "type" => "array",
        "default" => [],
        "children" => [
            // This hashtag defines, that we expect repeatable children of the same type
            "#" => [
                'type' => 'string',
                'filter' => function(string $v): string{
                    return strtolower($v);
                }
                'validator' => ['how', 'are', 'you']
            ]
        ]
    ]
]);

// $options will look like:
// [
//     "foo" => [
//        'how', 'are', 'you'
//     ]
// ];
```

Boolean Flags
-------------

[](#boolean-flags)

It is also possible to supply options that have a type of "boolean" as "flags," which means you don't have to provide any values to it. NOTE: Boolean Flags can only be used to set a boolean value to TRUE if you want to set it to FALSE you have to set the key, value pair.

```
use Neunerlei\Options\Options;
function myFunc(array $options = []){
    // Apply the options
    $options = Options::make($options, [
        "foo" => [
            "type" => "bool",
            "default" => false
        ]
    ]);
    print_r($options);
}

myFunc(); // Prints: ["foo" => false]
myFunc(["foo"]); // Prints: ["foo" => true]
myFunc(["foo" => true]); // Prints: ["foo" => true]
```

Additional options
------------------

[](#additional-options)

The third parameter of the Options::make() method lets you define additional options. All boolean values can be either passed as key-value pairs or as boolean flags.

#### allowUnknown (bool)

[](#allowunknown-bool)

*DEFAULT: FALSE*

If set to TRUE, unknown keys will be kept in the result.

#### ignoreUnknown (bool)

[](#ignoreunknown-bool)

*DEFAULT: FALSE*

If set to TRUE, unknown keys will be ignored but removed from the result.

#### allowBooleanFlags (bool)

[](#allowbooleanflags-bool)

*DEFAULT: TRUE*

If set to FALSE, it is not allowed to use boolean flags in your input array. Useful when validating API inputs.

Single value handling
---------------------

[](#single-value-handling)

In general, this does the same as Options::make() but is designed to validate non-array options.

NOTE: There is one gotcha. As you see in our example, we define $anOption as = null in the signature. This will cause the method to use the default value of " foo" if the property is not set. So make sure, if you want to allow NULL as non-default value to use a callback as default and handle null on your own.

```
use Neunerlei\Options\Options;
function myFunc($value, $anOption = null){
   $anOption = Options::makeSingle("anOption", $anOption, [
       "type" => ["string"],
       "default" => "foo",
   ]);
}
```

Usage without static class
--------------------------

[](#usage-without-static-class)

The static class uses a singleton of the `Neunerlei\Options\Applier\Applier` class for all its actions. So if you want to use the applier as a service using dependency injection, just use the applier class instead of the static Options class.

Extending the applier class
---------------------------

[](#extending-the-applier-class)

The static Options class has a public, static property called `$applierClass`, which defines the name of the class used for the logic. If you should ever want to extend the functionality, you can simply extend the applier class and set `Options::$applierClass` to the name of your extended class and will be good to go.

Special Thanks
--------------

[](#special-thanks)

Special thanks go to the folks at [LABOR.digital](https://labor.digital/) (which is the german word for laboratory and not the English "work" :D) for making it possible to publish my code online.

Postcardware
------------

[](#postcardware)

You're free to use this package, but if it makes it to your production environment, I highly appreciate you sending me a postcard from your hometown, mentioning which of our package(s) you are using.

You can find my address [here](https://www.neunerlei.eu/).

Thank you :D

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance49

Moderate activity, may be stable

Popularity15

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity58

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

Recently: every ~160 days

Total

9

Last Release

1593d ago

Major Versions

0.0.1 → 1.0.02020-03-01

1.2.1 → 2.0.02022-02-21

### Community

Maintainers

![](https://www.gravatar.com/avatar/0eb1c26fb5a535cd7a656faffbae7929009558b2bfa6156b2be7b636d689e13a?d=identicon)[labor-digital](/maintainers/labor-digital)

![](https://www.gravatar.com/avatar/c0356afb258572c8908df3132ea59545b7642a6b77fd90bc54215e506c42bfb7?d=identicon)[neunerlei](/maintainers/neunerlei)

---

Top Contributors

[![Neunerlei](https://avatars.githubusercontent.com/u/22350956?v=4)](https://github.com/Neunerlei "Neunerlei (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/neunerlei-options/health.svg)

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

###  Alternatives

[imi/magento2-store-switch-all-store-views

This module makes all store views available in the store switcher, regardless of their store or website.

1826.0k](/packages/imi-magento2-store-switch-all-store-views)[aschmelyun/size

Simple PHP helper to convert bytes to different sizes

471.2k](/packages/aschmelyun-size)

PHPackages © 2026

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