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

1594d 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

[ralouphie/getallheaders

A polyfill for getallheaders.

3.8k928.3M108](/packages/ralouphie-getallheaders)[jasongrimes/paginator

A lightweight PHP paginator, for generating pagination controls in the style of Stack Overflow and Flickr. The 'first' and 'last' page links are shown inline as page numbers, and excess page numbers are replaced by ellipses.

4091.3M22](/packages/jasongrimes-paginator)[flarum/core

Delightfully simple forum software.

201.4M2.3k](/packages/flarum-core)[bluedragon/laravel-routes

Publish Laravel routes to JavaScript

1292.8k](/packages/bluedragon-laravel-routes)

PHPackages © 2026

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