no message
This commit is contained in:
Vendored
+304
@@ -0,0 +1,304 @@
|
||||
Nette Schema
|
||||
************
|
||||
|
||||
[](https://packagist.org/packages/nette/schema)
|
||||
[](https://travis-ci.org/nette/schema)
|
||||
[](https://coveralls.io/github/nette/schema?branch=master)
|
||||
[](https://github.com/nette/schema/releases)
|
||||
[](https://github.com/nette/schema/blob/master/license.md)
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Handy library for validating data structures against a given Schema.
|
||||
|
||||
Documentation can be found on the [website](https://doc.nette.org/schema).
|
||||
|
||||
If you like Nette, **[please make a donation now](https://nette.org/donate)**. Thank you!
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
The recommended way to install is via Composer:
|
||||
|
||||
```
|
||||
composer require nette/schema
|
||||
```
|
||||
|
||||
It requires PHP version 7.1 and supports PHP up to 7.4.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
```php
|
||||
$processor = new Nette\Schema\Processor;
|
||||
|
||||
try {
|
||||
$normalized = $processor->process($schema, $data);
|
||||
} catch (Nette\Schema\ValidationException $e) {
|
||||
echo 'Data are not valid: ' . $e->getMessage();
|
||||
}
|
||||
|
||||
// in case of error it throws Nette\Schema\ValidationException
|
||||
|
||||
```
|
||||
|
||||
Defining schema
|
||||
---------------
|
||||
|
||||
```php
|
||||
use Nette\Schema\Expect;
|
||||
|
||||
$schema = Expect::structure([
|
||||
'processRefund' => Expect::bool(),
|
||||
'refundAmount' => Expect::int(),
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'processRefund' => true,
|
||||
'refundAmount' => 17,
|
||||
];
|
||||
|
||||
$normalized = $processor->process($schema, $data); // validates!
|
||||
```
|
||||
|
||||
If you're validating data passed, you can cast strings and booleans to the expected types defined by your schema:
|
||||
|
||||
```php
|
||||
$schema = Expect::structure([
|
||||
'processRefund' => Expect::scalar()->castTo('bool'),
|
||||
'refundAmount' => Expect::scalar()->castTo('int'),
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'processRefund' => 1,
|
||||
'refundAmount' => '17',
|
||||
];
|
||||
|
||||
$normalized = $processor->process($schema, $data); // validates!
|
||||
|
||||
is_bool($normalized->processRefund); // true
|
||||
is_int($normalized->refundAmount); // true
|
||||
```
|
||||
|
||||
If your schema contains default values, you can have these automatically applied during validation (by default, all properties are optional and have default value `null`):
|
||||
|
||||
```php
|
||||
$schema = Expect::structure([
|
||||
'processRefund' => Expect::bool()->default(true), // or Expect::bool(true)
|
||||
'refundAmount' => Expect::int(),
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'refundAmount' => 17,
|
||||
];
|
||||
|
||||
// validates, and sets defaults for missing properties
|
||||
$normalized = $processor->process($schema, $data);
|
||||
|
||||
// $normalized->processRefund === true;
|
||||
```
|
||||
|
||||
|
||||
Arrays of items
|
||||
---------------
|
||||
|
||||
Array where string keys are allowed:
|
||||
|
||||
```php
|
||||
$schema = Expect::arrayOf('string');
|
||||
|
||||
$processor->process($schema, ['key1' => 'a', 'key2' => 'b']); // validates
|
||||
$processor->process($schema, ['key' => 123]); // error: The option 'key' expects to be string, int 123 given.
|
||||
```
|
||||
|
||||
Indexed array with only numeric keys:
|
||||
|
||||
```php
|
||||
$schema = Expect::listOf('string');
|
||||
|
||||
$processor->process($schema, ['a', 'b']); // validates
|
||||
$processor->process($schema, ['key' => 'a']); // error, unexpected 'key'
|
||||
```
|
||||
|
||||
Enumerated values and anyOf()
|
||||
-----------------------------
|
||||
|
||||
The `anyOf()` is used to restrict a value to a fixed set of values or subschemes. It must be an array with at least one element:
|
||||
|
||||
```php
|
||||
$schema = Expect::listOf(
|
||||
Expect::anyOf('a', true, null)
|
||||
);
|
||||
|
||||
$processor->process($schema, ['a', true, null, 'a']); // validates
|
||||
$processor->process($schema, ['a', false]); // error: The option '1' expects to be 'a'|true|null, false given.
|
||||
```
|
||||
|
||||
Elements can be schema:
|
||||
|
||||
```php
|
||||
$schema = Expect::listOf(
|
||||
Expect::anyOf(Expect::string(), true, null)
|
||||
);
|
||||
|
||||
$processor->process($schema, ['foo', true, null, 'bar']); // validates
|
||||
$processor->process($schema, [123]); // error: The option '0' expects to be string|true|null, 123 given.
|
||||
```
|
||||
|
||||
Structures
|
||||
----------
|
||||
|
||||
Structures are objects with defined keys. Each of these key => pairs is conventionally referred to as a “property”.
|
||||
|
||||
By default, all properties are optional and have default value `null`. You can define mandatory properties via `required()`:
|
||||
|
||||
```php
|
||||
$schema = Expect::structure([
|
||||
'required' => Expect::string()->required(),
|
||||
'optional' => Expect::string(), // default is null
|
||||
]);
|
||||
|
||||
$processor->process($schema, ['optional' => '']); // error: option 'required' is missing
|
||||
$processor->process($schema, ['required' => 'foo']); // validates, returns (object) ['required' => 'foo', 'optional' => null]
|
||||
```
|
||||
|
||||
You can define nullable properties via `nullable()`:
|
||||
|
||||
```php
|
||||
$schema = Expect::structure([
|
||||
'optional' => Expect::string(),
|
||||
'nullable' => Expect::string()->nullable(),
|
||||
]);
|
||||
|
||||
$processor->process($schema, ['optional' => null]); // error: 'optional' expects to be string, null given.
|
||||
$processor->process($schema, ['nullable' => null]); // validates, returns (object) ['optional' => null, 'nullable' => null]
|
||||
```
|
||||
|
||||
By default, providing additional properties is forbidden:
|
||||
|
||||
```php
|
||||
$schema = Expect::structure([
|
||||
'key' => Expect::string(),
|
||||
]);
|
||||
|
||||
$processor->process($schema, ['additional' => 1]); // error: Unexpected option 'additional'
|
||||
```
|
||||
|
||||
The `otherItems()` is used to control the handling of extra stuff, that is, properties whose names are not listed in `Expect::structure()`:
|
||||
|
||||
```php
|
||||
$schema = Expect::structure([
|
||||
'key' => Expect::string(),
|
||||
])->otherItems(Expect::int());
|
||||
|
||||
$processor->process($schema, ['additional' => 1]); // validates
|
||||
```
|
||||
|
||||
Size and ranges
|
||||
---------------
|
||||
|
||||
The number of properties on an object can be restricted using the `min()` and `max()`:
|
||||
|
||||
```php
|
||||
// array, at least 10 items, maximum 20 items
|
||||
$schema = Expect::array()->min(10)->max(20);
|
||||
```
|
||||
|
||||
The length of a string can be constrained using the `min()` and `max()`:
|
||||
|
||||
```php
|
||||
// string, at least 10 characters long, maximum 20 characters
|
||||
$schema = Expect::string()->min(10)->max(20);
|
||||
```
|
||||
|
||||
Ranges of numbers are specified using a combination of `min()` and `max()`:
|
||||
|
||||
```php
|
||||
// at least 10, maximum 20 characters
|
||||
$schema = Expect::int()->min(10)->max(20);
|
||||
```
|
||||
|
||||
Data mapping to objects
|
||||
-----------------------
|
||||
|
||||
Schema can be generated from class:
|
||||
|
||||
```php
|
||||
class Config {
|
||||
/** @var string */
|
||||
public $dsn;
|
||||
|
||||
/** @var string|null */
|
||||
public $user;
|
||||
|
||||
/** @var string|null */
|
||||
public $password;
|
||||
|
||||
/** @var bool */
|
||||
public $debugger = true;
|
||||
}
|
||||
|
||||
$schema = Expect::from(new Config);
|
||||
|
||||
$data = [
|
||||
'dsn' => 'sqlite',
|
||||
'user' => 'root'
|
||||
];
|
||||
|
||||
$normalized = $processor->process($schema, $data);
|
||||
// $normalized is Config class
|
||||
// $normalized->dsn === 'sqlite'
|
||||
// $normalized->user === 'root'
|
||||
// $normalized->password === null
|
||||
// $normalized->debugger === true
|
||||
```
|
||||
|
||||
You can even use PHP 7.4 notation:
|
||||
|
||||
|
||||
```php
|
||||
class Config {
|
||||
public string $dsn;
|
||||
public ?string $user;
|
||||
public ?string $password;
|
||||
public bool $debugger = true;
|
||||
}
|
||||
|
||||
$schema = Expect::from(new Config);
|
||||
```
|
||||
|
||||
Or use anonymous class:
|
||||
|
||||
```php
|
||||
$schema = Expect::from(new class {
|
||||
public string $dsn;
|
||||
public ?string $user;
|
||||
public ?string $password;
|
||||
public bool $debugger = true;
|
||||
});
|
||||
```
|
||||
|
||||
Custom normalization
|
||||
--------------------
|
||||
|
||||
```php
|
||||
$schema = Expect::arrayOf('string')
|
||||
->before(function ($v) { return explode(' ', $v); });
|
||||
|
||||
$normalized = $processor->process($schema, 'a b c'); // validates and returns ['a', 'b', 'c']
|
||||
```
|
||||
|
||||
Custom constraints
|
||||
------------------
|
||||
|
||||
```php
|
||||
$schema = Expect::arrayOf('string')
|
||||
->assert(function ($v) { return count($v) % 2 === 0; }); // count must be even number
|
||||
|
||||
$processor->process($schema, ['a', 'b']); // validates, 2 is even number
|
||||
$processor->process($schema, ['a', 'b', 'c']); // error, 3 is not even number
|
||||
```
|
||||
Reference in New Issue
Block a user