zheltikov / php-type-assert
Requires
- php: >=7.4
- ext-json: *
- myclabs/php-enum: ^1.8
- tmilos/lexer: ^1.0
- zheltikov/php-exceptions: ^1.0
- zheltikov/php-invariant: ^1.1
- zheltikov/php-memoize: ^2.0
Requires (Dev)
- ircmaxell/php-yacc: ^0.0.7
- nazar-pc/phpt-tests-runner: ^1.4
README
A type checking/assertion library for PHP, for more compact and secure code.
Installation
As this is a Composer package, you can install it via:
$ composer require zheltikov/php-type-assert
Usage
This library exposes three functions in the \Zheltikov\TypeAssert
namespace:
is_(mixed, string): bool
as_(mixed, string): mixed
null_as_(mixed, string): mixed|null
Example
You may use these functions as follows:
<?php require_once(__DIR__ . '/../vendor/autoload.php'); use Zheltikov\TypeAssert\{is_, as_, null_as_}; // Using `is_()` to check types is_(1, 'int'); // true is_('foo', 'int'); // false is_(1, 'num'); // true is_(1.5, 'num'); // true is_('foo', 'num'); // false is_('mykey', '?arraykey'); // true is_('bar', '!num'); // true is_('X', 'char'); // true // Enforcing types with `as_()` as_(1, 'int'); // 1 as_('foo', 'int'); // TypeAssertionException as_(123, '?num'); // 123 as_('bar', '?num'); // TypeAssertionException // Get `null` if the type does not match with `null_as_()` null_as_(1, 'int'); // 1 null_as_('foo', 'int'); // null null_as_(123, '?num'); // 123 null_as_('bar', '?num'); // null // As you can see performing type checks with these functions is much more // compact that doing it with `if`s // For example, instead of... if (is_int($value) || is_float($value)) { // do something } // ...use... if (is_($value, 'num')) { // do something } // ...or even... as_($value, 'num'); // do something
Below comes a simple explanation for each function:
is_(mixed, string): bool
Parameters:
mixed $value
string $type
Checks whether the value in $value
has the type specified in $type
, and returns a boolean result.
as_(mixed, string): mixed
Parameters:
mixed $value
string $expected
Performs the same checks as is_
. However, it throws TypeAssertionException
if the value has a different type. If the
type matches, it returns the original value.
null_as_(mixed, string): mixed|null
Parameters:
mixed $value
string $expected
Similar to as_
, but which returns null if the type does not match.
Supported types and type interpretation
Here comes a list of the supported types and how they are checked internally:
TODO
- Support for built-in PHP types
- Support for
null
andnonnull
- Support for
empty
andnonempty
- Support for
mixed
andvoid
- Support for
num
- Support for
arraykey
- Support for nullable types
- Support for negated types
- Support for
classname
,interfacename
andtraitname
- Support for
char
- Support for
Stringish
: any string-like value - Support for custom classnames
- Support for
true
andfalse
- Support for
positive
,nonpositive
andnotpositive
- Support for
negative
,nonnegative
andnotnegative
- Support for tuples. For example:
tuple(int, ?DateTime, bool)
- Support for closed shapes. For example:
shape('id' => int, 'name' => string)
- Support for open shapes. For example:
shape('id' => int, 'name' => string, ...)
- Support for optional shape fields. For example:
shape('id' => int, ?'name' => string)
- Support for enums:
- Check by enum type
- Check by enum field name
- Support for array generics
- By value. For example:
array<User>
- By key and value. For example:
array<string, int>
- By value. For example:
- Support for unions. For example:
int|string|null
- Support for intersections. For example:
Exception&Throwable
- Modularity, ability to define custom checker functions and types
- Memoize some checker functions
- Support for type alias definitions
- Support for type precedence checking definition
- Support for comments
- Support for format strings (like for
sprintf
andsscanf
) - Support for regular expressions
- Support for named parameters
- Support for open tuples:
tuple(int, ...)
,tuple(..., int)
,tuple(int, ..., int)
- Support for error (type mismatch) reporting, for humans :)
- Support for callable types:
- Support for fixed-count parameters:
(function(string, int): array<string, int>)
- Support for variable-count parameters:
(function(string, ...): int)
- Support for fixed-count parameters:
- Support for raw integers
- Support for raw floats
- Support for shape integer keys
- The function
as_
should convert (cast) the value, rather than checking it. Use some (extendable) converter class.
Performance
You may ask about the performance impact of this parsing process on the overall request. You will be surprised hearing that the performance of the parser included in this library is actually pretty good.
Some tests were made, in which the following type string was being parsed:
shape(
'id' => int & positive,
'name' => string,
'price' => float & positive,
'score' => null | (int & positive),
'description' => string,
'photo_id' => int & positive,
'category_id' => int & positive
)
This test was performed on PHP v7.4 and PHP v8.0 with JIT compilation enabled, and the result aren't bad at all!:
Note: these performance tests were made at commit d9fedd23...
, therefore they may not be accurate for the latest
library version.