|
1 | | -# CheckType |
| 1 | +# Bermuda Types |
2 | 2 |
|
3 | | -A lightweight PHP library for determining and enforcing variable types. |
| 3 | +Runtime type checking and validation library for PHP 8.4+. |
4 | 4 |
|
5 | | -Легковесная PHP-библиотека для определения и обеспечения типов переменных. |
| 5 | +## Installation |
6 | 6 |
|
7 | | ---- |
| 7 | +```bash |
| 8 | +composer require bermudaphp/types |
| 9 | +``` |
| 10 | + |
| 11 | +## Features |
| 12 | + |
| 13 | +- Runtime type checking and validation via `Types` class |
| 14 | +- Support for built-in PHP types and custom classes |
| 15 | +- Type assertions with detailed error messages |
| 16 | +- Backward compatibility with legacy `enforce()` method |
| 17 | +- Full PHP 8.4 compatibility with typed constants |
| 18 | +- Static analysis friendly (PHPStan Level 9, Psalm Level 1) |
| 19 | +- Zero dependencies |
| 20 | +- Lightweight and performant |
| 21 | + |
| 22 | +## Types Utility |
8 | 23 |
|
9 | | -## Features / Возможности |
| 24 | +The `Types` class provides comprehensive runtime type checking and validation. |
10 | 25 |
|
11 | | -- **Type Detection / Определение Типа** |
12 | | - Provides the `getType()` method to determine the type of any given variable, including returning class names when desired. |
| 26 | +### Basic Type Checking |
13 | 27 |
|
14 | | -- **Type Enforcement / Обеспечение Типов** |
15 | | - Enforces allowed types using the `enforce()` method, throwing detailed error messages with caller information when expectations are not met. |
| 28 | +```php |
| 29 | +use Bermuda\Stdlib\Types; |
16 | 30 |
|
17 | | -- **Class & Interface Checks / Проверка Классов и Интерфейсов** |
18 | | - Validates class and interface names with `isClass()` and `isInterface()` methods, ensuring accurate type checks. |
| 31 | +// Check basic types |
| 32 | +Types::is($value, Types::TYPE_STRING); // true if string |
| 33 | +Types::is($value, Types::TYPE_INT); // true if integer |
| 34 | +Types::is($value, 'array'); // true if array |
19 | 35 |
|
20 | | -- **Flexible Configuration / Гибкая Настройка** |
21 | | - Uses bitmask flags such as `FLAG_OBJECT_AS_CLASS` and `FLAG_CALLABLE_AS_OBJECT` to customize behavior. |
| 36 | +// Check multiple types |
| 37 | +Types::isAny($value, [Types::TYPE_STRING, Types::TYPE_INT]); // true if string OR int |
22 | 38 |
|
23 | | ---- |
| 39 | +// Check object instances |
| 40 | +Types::is($user, User::class); // true if $user instanceof User |
| 41 | +Types::isInstanceOf($user, UserInterface::class); // true if implements interface |
| 42 | +``` |
24 | 43 |
|
25 | | -## Installation / Установка |
| 44 | +### Type Assertions |
26 | 45 |
|
27 | | -This library requires **PHP 8.0** or higher. |
| 46 | +```php |
| 47 | +use Bermuda\Stdlib\Types; |
28 | 48 |
|
29 | | -Эта библиотека требует **PHP 8.0** или выше. |
| 49 | +// Throws InvalidArgumentException if not matching |
| 50 | +Types::assert($value, Types::TYPE_STRING); |
| 51 | +Types::assert($value, [Types::TYPE_STRING, Types::TYPE_INT]); |
30 | 52 |
|
31 | | -Install via Composer: |
| 53 | +// enforce() is an alias for assert() (backward compatibility) |
| 54 | +Types::enforce($value, Types::TYPE_STRING); |
32 | 55 |
|
33 | | -Установите через Composer: |
| 56 | +// Assert not null with type check |
| 57 | +$user = Types::assertNotNull($maybeUser, User::class); |
| 58 | +// $user is guaranteed to be non-null User instance |
34 | 59 |
|
35 | | -```bash |
36 | | -composer require bermudaphp/checktype |
| 60 | +// Custom error messages |
| 61 | +Types::assert($value, Types::TYPE_INT, 'ID must be an integer'); |
| 62 | +``` |
| 63 | + |
| 64 | +### Advanced Type Detection |
| 65 | + |
| 66 | +```php |
| 67 | +use Bermuda\Stdlib\Types; |
| 68 | + |
| 69 | +// Get the actual type |
| 70 | +$type = Types::getType($value); // returns 'string', 'int', 'array', etc. |
| 71 | + |
| 72 | +// Get class name for objects |
| 73 | +$type = Types::getType($object, Types::OBJECT_AS_CLASS); // returns 'App\User' |
| 74 | + |
| 75 | +// Handle callables as objects |
| 76 | +$type = Types::getType($callable, Types::CALLABLE_AS_OBJECT); |
37 | 77 | ``` |
38 | 78 |
|
39 | | -## Usage / Использование |
| 79 | +### Class and Interface Validation |
| 80 | + |
40 | 81 | ```php |
41 | | -use Bermuda\CheckType\Type; |
| 82 | +use Bermuda\Stdlib\Types; |
42 | 83 |
|
43 | | -$value = 42; |
| 84 | +// Check if string is a valid class name |
| 85 | +Types::isClass('App\User'); // true if class exists |
| 86 | +Types::isClass($value, User::class); // true if $value === 'App\User' (case-insensitive) |
44 | 87 |
|
45 | | -// Determine the type of the variable |
46 | | -echo Type::getType($value); // Outputs: int |
| 88 | +// Check if string is a valid interface name |
| 89 | +Types::isInterface('App\UserInterface'); // true if interface exists |
47 | 90 |
|
48 | | -// Enforce allowed types |
49 | | -Type::enforce(static fn() => 42, [Type::TYPE_CALLABLE, \Closure::class]); |
| 91 | +// Check subclass relationships |
| 92 | +Types::isSubclassOf('App\Admin', 'App\User'); // true if Admin extends User |
| 93 | +Types::isSubclassOfAny('App\Admin', ['App\User', 'App\Manager']); |
50 | 94 | ``` |
| 95 | + |
| 96 | +### Real-world Examples |
| 97 | + |
| 98 | +```php |
| 99 | +use Bermuda\Stdlib\Types; |
| 100 | + |
| 101 | +class UserService |
| 102 | +{ |
| 103 | + public function createUser(mixed $data): User |
| 104 | + { |
| 105 | + Types::assert($data, Types::TYPE_ARRAY, 'User data must be an array'); |
| 106 | + |
| 107 | + $id = Types::assertNotNull($data['id'] ?? null, Types::TYPE_INT); |
| 108 | + $email = Types::assertNotNull($data['email'] ?? null, Types::TYPE_STRING); |
| 109 | + |
| 110 | + return new User($id, $email); |
| 111 | + } |
| 112 | + |
| 113 | + public function processPayment(mixed $handler): void |
| 114 | + { |
| 115 | + Types::assert($handler, [ |
| 116 | + PaymentInterface::class, |
| 117 | + Types::TYPE_CALLABLE |
| 118 | + ], 'Payment handler must implement PaymentInterface or be callable'); |
| 119 | + |
| 120 | + // Process payment... |
| 121 | + } |
| 122 | +} |
| 123 | +``` |
| 124 | + |
| 125 | +## API Reference |
| 126 | + |
| 127 | +### Type Constants |
| 128 | + |
| 129 | +- `Types::TYPE_ARRAY` - Array type |
| 130 | +- `Types::TYPE_OBJECT` - Object type |
| 131 | +- `Types::TYPE_INT` - Integer type |
| 132 | +- `Types::TYPE_BOOL` - Boolean type |
| 133 | +- `Types::TYPE_STRING` - String type |
| 134 | +- `Types::TYPE_RESOURCE` - Resource type |
| 135 | +- `Types::TYPE_CALLABLE` - Callable type |
| 136 | +- `Types::TYPE_FLOAT` - Float type |
| 137 | +- `Types::TYPE_NULL` - Null type |
| 138 | + |
| 139 | +### Flag Constants |
| 140 | + |
| 141 | +- `Types::CALLABLE_AS_OBJECT` - Treat callable objects as objects |
| 142 | +- `Types::OBJECT_AS_CLASS` - Return class name instead of 'object' |
| 143 | + |
| 144 | +### Methods |
| 145 | + |
| 146 | +#### `getType(mixed $value, int $flags = 0): string` |
| 147 | +Determines the type of a variable. |
| 148 | + |
| 149 | +#### `is(mixed $value, string $expectedType): bool` |
| 150 | +Checks if the value matches the specified type. |
| 151 | + |
| 152 | +#### `isAny(mixed $value, array $expectedTypes): bool` |
| 153 | +Checks if the value matches any of the provided types. |
| 154 | + |
| 155 | +#### `assert(mixed $value, string|array $expectedTypes, ?string $message = null): void` |
| 156 | +Asserts that the value matches one of the allowed types. |
| 157 | + |
| 158 | +#### `enforce(mixed $value, string|array $expectedTypes, ?string $message = null): void` |
| 159 | +Alias for assert() method (backward compatibility). |
| 160 | + |
| 161 | +#### `assertNotNull(mixed $value, string|array $expectedTypes, ?string $message = null): mixed` |
| 162 | +Asserts that the value is not null and matches one of the allowed types. |
| 163 | + |
| 164 | +#### `isClass(mixed $value, ?string $expectedClass = null): bool` |
| 165 | +Checks if the value is a valid class name. |
| 166 | + |
| 167 | +#### `isInterface(mixed $value, ?string $expectedInterface = null): bool` |
| 168 | +Checks if the value is a valid interface name. |
| 169 | + |
| 170 | +#### `isSubclassOf(mixed $value, string $parentClass): bool` |
| 171 | +Checks if the value is a subclass of the specified class. |
| 172 | + |
| 173 | +#### `isInstanceOf(mixed $value, string $className): bool` |
| 174 | +Checks if the value is an instance of the specified class or interface. |
| 175 | + |
| 176 | +## License |
| 177 | + |
| 178 | +MIT License. See LICENSE file for details. |
0 commit comments