f2 / types
Data type declarations with casting, validation and annotations, without DocBlock parsing using pure PHP.
Requires (Dev)
- f2/asserty: ^1.0
This package is not auto-updated.
Last update: 2024-12-13 18:37:40 UTC
README
Provides a consistent and simple type system with casting and testing of types, using pure PHP and no DocBlock comments.
It works with native PHP types, and can be combined with any other software without interfering.
Types supported
Type\BOOL
Type\INT
Type\FLOAT
Type\NUMBER
Type\STRING
Type\ARR
Type\OBJ
Type\RESOURCE
Type\TYPE
Type\CALLBACK
Type\CLASSNAME
Use Cases
Metadata about a schema
For example when declaring a database schema:
$user = [
// 'id' can be either an integer or null
'id' => Type\INT + Type\NUL,
// These fields must be strings, and 'length' is a custom annotation
'username' => Type\STRING + [ 'length' => 50 ],
'first_name' => Type\STRING + [ 'length' => 50 ],
'last_name' => Type\STRING + [ 'length' => 50 ],
// 'last_login' can be either a string or null
'last_login' => Type\STRING + Type\NUL,
];
It is flexible to use for the static context of a class:
use F2\Type;
class User {
// Types can be combined
protected $id = Type\INT + Type\NUL;
protected $username = Type\STRING + [
// Custom annotations must not start with '#'
'caption' => 'Username',
'field_type' => 'VARCHAR(20)',
// Built in annotations for validation and more
'#required' => true,
'#validator' => [ self::class, 'usernameValidator' ],
];
protected $notes = Type\STRING + [
'#required' => false,
'#maxlen' => 1000,
];
protected $first_name = Type\STRING + [
'caption' => 'Given Name',
'field_type' => 'VARCHAR(30)'
'#required' => true,
'#minlen' => 1,
'#maxlen' => 30,
'#ctype' => 'alpha',
];
protected $last_name = Type\STRING + [
'caption' => 'Family Name',
'#minlen' => 1,
'#maxlen' => 30,
'#ctype' => 'alpha',
];
protected $last_login = Type\STRING + Type\NUL;
}
You can create a library of centrally managed types and annotations by declaring constants:
use F2\Type;
class CustomTypes {
const REQUIRED = [
'#NOT' => [ null, '' ],
];
const EMAIL = Type\STRING + [
'#for' => 'email'
];
const NAME = Type\STRING + [
'#minlen' => 1,
'#maxlen' => 30,
'#preg' => '|[A-Z][a-zA-Z\ ]+[a-z]|',
];
/**
* Added here to illustrate the use case
*/
protected $exampleField = CustomTypes::NAME + CustomTypes::REQUIRED + [
'caption' => 'Example Field',
];
}
Examples
Basic type testing
use F2\Type;
Type::is( 123, Type\INT ); // true
Type::is( 123, Type\FLOAT ); // false
Type::is( 123.0, Type\INT ); // false
Type::is( 123, Type\NUMBER ); // true
Type::is( 123.0, Type\NUMBER ); // true
Type::is( 123, Type\STRING ); // false
Type::is( "123", Type\STRING ); // true
Test a combination of types
Type::is( 123.0, Type\STRING + Type\FLOAT ); // true
Type::is( "123", Type\STRING + Type\FLOAT ); // true
Type::is( 123, Type\STRING + Type\FLOAT ); // false because 123 is an integer
Type casting
use F2\Type;
Type\INT( "123 " ); // 123
Type\STRING( 123 ); // "123"
Type\BOOL( 1 ); // true
Type\BOOL( 0 ); // false
Type::as( "123", Type\INT ) // 123
Type::as( "123", Type::of(10.0) ) // 123.0
Get type of any value
use F2\Type;
Type::of(10.00) // Type\FLOAT
Extensively unit tested
The library is extensively unit tested with more than 700 tests, to detect any incompatabilities between releases, but it has not been used in production yet.
Please let me know if you plan to use it in any framework or application.