Skip to content
/ schema Public
forked from nette/schema

πŸ“ Validating data structures against a given Schema.

License

Notifications You must be signed in to change notification settings

integer/schema

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Nette Schema


Downloads this Month Build Status Coverage Status Latest Stable Version License

Introduction

Handy library for validating data structures against a given Schema.

Documentation can be found on the website.

If you like Nette, please make a donation now. 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

$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

use Nette\Schema\Expect;

$schema = Expect::structure([
    'processRefund' => Expect::bool(),
    'refundAmount' => Expect::int(),
]);

$data = [
    'processRefund' => true,
    'refundAmount' => 17,
];

$normalized = $processor->process($schema, $data); // it passes

If you're validating data passed, you can cast strings and booleans to the expected types defined by your schema:

$schema = Expect::structure([
    'processRefund' => Expect::scalar()->castTo('bool'),
    'refundAmount' => Expect::scalar()->castTo('int'),
]);

$data = [
    'processRefund' => 1,
    'refundAmount' => '17',
];

$normalized = $processor->process($schema, $data); // it passes

is_bool($normalized->processRefund); // true
is_int($normalized->refundAmount); // true

By default, all properties are optional and have default value null, or [] in the case of arrays.

You can change the default value as follows:

$schema = Expect::structure([
    'processRefund' => Expect::bool()->default(true), // or Expect::bool(true)
]);

$data = [];

// validates, and sets defaults for missing properties
$normalized = $processor->process($schema, $data);

// $normalized->processRefund === true;

Arrays of items

Array where only string items are allowed:

$schema = Expect::arrayOf('string');

$processor->process($schema, ['key1' => 'a', 'key2' => 'b']); // it passes
$processor->process($schema, ['key' => 123]); // error: The option 'key' expects to be string, int 123 given.

Indexed array (ie. with numeric keys) where only string items are allowed:

$schema = Expect::listOf('string');

$processor->process($schema, ['a', 'b']); // it passes
$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 variants or subschemes:

$schema = Expect::listOf(
	Expect::anyOf('a', true, null)
);

$processor->process($schema, ['a', true, null, 'a']); // it passes
$processor->process($schema, ['a', false]); // error: The option '1' expects to be 'a'|true|null, false given.

Elements can be schema:

$schema = Expect::listOf(
	Expect::anyOf(Expect::string(), true, null)
);

$processor->process($schema, ['foo', true, null, 'bar']); // it passes
$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():

$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']); // it passes, returns (object) ['required' => 'foo', 'optional' => null]

You can define nullable properties via nullable():

$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]); // it passes, returns (object) ['optional' => null, 'nullable' => null]

By default, providing additional properties is forbidden:

$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():

$schema = Expect::structure([
	'key' => Expect::string(),
])->otherItems(Expect::int());

$processor->process($schema, ['additional' => 1]); // it passes

Size and ranges

You can limit the number of elements or properties using the min() and max():

// 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():

// 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():

// integer, between 10 and 20
$schema = Expect::int()->min(10)->max(20);

Regular expressions

String can be restricted by regular expression using the pattern():

// just 9 numbers
$schema = Expect::string()->pattern('\d{9}');

Data mapping to objects

Schema can be generated from class:

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:

class Config {
	public string $dsn;
	public ?string $user;
	public ?string $password;
	public bool $debugger = true;
}

$schema = Expect::from(new Config);

Or use anonymous class:

$schema = Expect::from(new class {
	public string $dsn;
	public ?string $user;
	public ?string $password;
	public bool $debugger = true;
});

Custom normalization

$schema = Expect::arrayOf('string')
	->before(function ($v) { return explode(' ', $v); });

$normalized = $processor->process($schema, 'a b c'); // it passes and returns ['a', 'b', 'c']

Custom constraints

$schema = Expect::arrayOf('string')
	->assert(function ($v) { return count($v) % 2 === 0; }); // count must be even number

$processor->process($schema, ['a', 'b']); // it passes, 2 is even number
$processor->process($schema, ['a', 'b', 'c']); // error, 3 is not even number

About

πŸ“ Validating data structures against a given Schema.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%