-
Notifications
You must be signed in to change notification settings - Fork 16
nspl\args
Helps to validate function arguments
Checks that argument satisfies the required constraints otherwise throws the corresponding exception
$constraints are callable(s) which return(s) true if the argument satisfies the requirements or it also might contain the required class name(s)
If $atPosition is null then position is calculated automatically comparing given argument to the actual arguments passed to the function
$otherwiseThrow defines exception which will be thrown if given argument is invalid, it can be the exception class or exception object
use const \nspl\args\int;
use const \nspl\args\string;
use const \nspl\args\arrayAccess;
use function \nspl\args\expects;
function nth($sequence, $n)
{
expects([arrayAccess, string], $sequence);
expects(int, $n);
return $sequence[$n];
}
nth('hello world', 'blah');Outputs:
InvalidArgumentException: Argument 2 passed to nth() must be integer, string 'blah' given in /path/to/example.php on line 17
Call Stack:
0.0002 230304 1. {main}() /path/to/example.php:0
0.0023 556800 2. sqr() /path/to/example.php:17
expectsAll($constraints, array $args, array $atPositions = [], $otherwiseThrow = '\InvalidArgumentException')
Checks that all specified arguments satisfy the required constraints otherwise throws the corresponding exception
use const \nspl\args\numeric;
use function \nspl\args\expects;
function sum($x, $y)
{
expectsAll(numeric, [$x, $y]);
return $x + $y;
}expectsOptional($constraints, $arg, $atPosition = null, $otherwiseThrow = '\InvalidArgumentException')
Checks that argument is null or satisfies the required constraints otherwise throws the corresponding exception
function splitBy($string, $separator = ' ', $limit = null)
{
expectsAll(string, [$string, $separator]);
expectsOptional(int, $limit);
return explode($separator, $string, $limit);
}The module provides predefined constraints. Which can be one of the two types:
- OR-constraints which are evaluated with
oroperator (e.g.expects([int, string], $arg)evaluates as$arghas to be anintor astring) - AND-constraints which are evaluated with
andoperator (e.g.expects([string, longerThan(3), shorterThan(10)], $arg)evaluates as$arghas to be a string longer than 3 characters and shorter than 10 characters). If you want to evaluate several AND-constraints as they were OR-constraints you can useanyconstraint. If you want to evaluate several OR-constraints as they were AND-constraints you can useallconstraint
| Callback | Explanation | Type |
|---|---|---|
| bool | Checks that argument is a bool | OR |
| int | Checks that argument is an int | OR |
| float | Checks that argument is a float | OR |
| numeric | Checks that argument is numeric | OR |
| string | Checks that argument is a string | OR |
| array_ | Checks that argument is an array | OR |
| object | Checks that argument is an object | OR |
| callable_ | Checks that argument is callable | OR |
| arrayKey | Checks that argument can be an array key | OR |
| traversable | Checks that argument can be traversed with foreach | OR |
| arrayAccess | Checks that argument supports array index access | OR |
| nonEmpty | Checks that argument is not empty | AND |
| positive | Checks that argument is positive (> 0) | AND |
| nonNegative | Checks that argument is not negative (>= 0) | AND |
| nonZero | Checks that argument is not zero (!== 0) | AND |
| any(constraint1, ..., constraintN) | Checks constraints as if they were OR-constraints | AND |
| all(constraint1, ..., constraintN) | Checks constraints as if they were AND-constraints | AND |
| not(constraint1, ..., constraintN) | Checks that argument does't satisfy all listed constraints | AND |
| values(value1, ..., valueN) | Checks that argument is one of the specified values | AND |
| longerThan($threshold) | Checks that string argument is longer than given threshold | AND |
| shorterThan($threshold) | Checks that string argument is shorter than given threshold | AND |
| biggerThan($threshold) | Checks that number is bigger than given threshold | AND |
| smallerThan($threshold) | Checks that number is smaller than given threshold | AND |
| hasKey($key) | Checks that argument supports array index access and has given key | AND |
| hasKeys($key1, ..., $keyN) | Checks that argument supports array index access and has given keys | AND |
| hasMethod($method) | Checks that argument is an object and has given method | AND |
| hasMethods($method1, ..., $methodN) | Checks that argument is an object and has given methods | AND |
function setUsername($username)
{
expects([string, longerThan(3), shorterThan(10)], $username);
// ...
}
function setState($state)
{
expects(values('running', 'idle', 'stopped'), $state);
// ...
} Duck-typing example:
class Service
{
// ...
public function setCache($cache)
{
expects(withMethods('set', 'get'), $cache);
$this->cache = $cache;
}
// ....
}It is possible to use custom constraints. Just define a new function which returns true when argument satisfies the constraint:
function even($value)
{
return is_int($value) && $value %2 === 0;
}
function half($number)
{
expects('even', $number);
return $number / 2;
}or we can make it more convenient to use introducing a constant:
const even = 'even';
function half($number)
{
expects(even, $number);
return $number / 2;
}
half('pie');Outputs:
InvalidArgumentException: Argument 1 passed to half() must be even, string 'pie' given in /path/to/example.php on line 25
Call Stack:
0.0009 253640 1. {main}() /path/to/example.php:0
0.0123 673984 2. half() /path/to/example.php:25
If you need to create a constraint which takes arguments you must create a callable object which implements \nspl\args\Constraint interface. It contains two methods:
-
__invoke($value)- returns true if the value satisfies the constraint -
__toString()- returns text which will be used in the exception when value doesn't satisfy the constraint. The text must contain message which goes after "must" in the exception message.