Download the PHP package nette/schema without Composer

On this page you can find all versions of the php package nette/schema. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package schema

Nette Schema

Downloads this Month Tests Coverage Status Latest Stable Version License

Introduction

A practical library for validating and normalizing data structures against a given schema with a smart, easy-to-understand API.

Documentation can be found on the website.

Installation:

It requires PHP version 8.1 and supports PHP up to 8.5.

Support Me

Do you like Nette Schema? Are you looking forward to the new features?

Buy me a coffee

Thank you!

Basic Usage

In the variable $schema, we have a validation schema (we'll explain what this means and how to create one in a moment), and in the variable $data, we have the data structure we want to validate and normalize. This could be, for example, data submitted by a user via an API, a configuration file, etc.

The task is handled by the Nette\Schema\Processor class, which processes the input and either returns normalized data or throws a Nette\Schema\ValidationException exception if an error occurs.

The method $e->getMessages() returns an array of all messages as strings, and $e->getMessageObjects() returns all messages as Nette\Schema\Message objects.

Defining the Schema

And now let's create the schema. The class Nette\Schema\Expect is used to define it; we essentially define expectations for what the data should look like. Let's say the input data must be a structure (e.g., an array) containing elements processRefund of type bool and refundAmount of type int.

We believe the schema definition looks understandable, even if you're seeing it for the first time.

Let's send the following data for validation:

The output, i.e., the value $normalized, is a stdClass object. If we wanted the output to be an array, we would add casting ->castTo('array') to the schema.

All elements of the structure are optional and have a default value of null. Example:

The fact that the default value is null does not mean it would accept 'processRefund' => null in the input data. No, the input must be a boolean, i.e. true or false only. We would have to explicitly allow null using Expect::bool()->nullable().

An item can be made mandatory using Expect::bool()->required(). We can change the default value, for example, to false using Expect::bool()->default(false) or shorthand Expect::bool(false).

And what if we wanted to accept 1 and 0 in addition to booleans? Then we list the values that we also want to normalize to boolean:

Now you know the basics of defining a schema and how the structure items behave. We will now show what other elements you can use when defining a schema.

Data Types: type()

All standard PHP data types can be specified in the schema:

And also all types supported by the Validators class, for example Expect::type('scalar') or shorthand Expect::scalar(). Also class or interface names, e.g., Expect::type('AddressEntity').

Union syntax can also be used:

The default value is always null with the exception of array and list, where it is an empty array. (A list is an array indexed by a sequence of numeric keys starting from zero, i.e. a non-associative array).

Array of Values: arrayOf() listOf()

An array represents too general a structure; it's more useful to specify precisely which elements it may contain. For example, an array whose elements can only be strings:

The second parameter can specify keys (since version 1.2):

A list is an indexed array:

With the wrap parameter, a single value is also accepted and wrapped into a one-item list (since version 1.4):

The parameter can also be a schema, so we can write:

The default value is an empty array. If you specify a default value and call mergeDefaults(), it will be merged with the passed data.

Enumeration: anyOf()

anyOf() represents a set of values or schemas that a value can take. Here's how to write an array of elements that can be either 'a', true, or null:

The elements of the enumeration can also be schemas:

The anyOf() method accepts variants as separate parameters, not as an array. To pass it an array of values, use the unpack operator anyOf(...$variants).

Variants are tried in the order they are written and the first matching one wins. The single exception is null: when it belongs to the accepted values, a null input always gives null, even though a structure or an array variant would otherwise read it as an empty value of its own.

The default value is null. Use the firstIsDefault() method to make the first item the default:

Enums: enum()

A configuration file can only carry a plain string like 'hearts', but in your code you would much rather work with an enum. That is the gap enum() closes (since version 1.4): give it an enum with a backing value (enum Suit: string) and it accepts either the backing value or the case itself, always handing you back the case:

Enums backed by integers work exactly the same, and so does everything you know from the other elements, such as Expect::enum(Suit::class)->required() or ->default(Suit::Hearts).

You often do not have to reach for enum() explicitly. An enum class name is recognized in a type expression and when generating a schema from a class, so Expect::type(Suit::class) and a public Suit $suit property give you the very same element.

Structures

Structures are objects with defined keys. Each key-value pair is referred to as a "property".

Structures accept arrays and objects and return stdClass objects.

By default, all properties are optional and have a default value of null. You can define mandatory properties using required():

A structure itself is mandatory. Therefore, if it is nested inside another structure and the input does not contain it, it is created anyway - and it reports an error when it contains a required property. Use required(false) to make the entire nested structure optional. If it is missing in the input, null appears in the output, but if it is present, its required properties are enforced:

If you do not want properties with default values in the output, use skipDefaults():

Although null is the default value for the optional property, it is not allowed in input data (the value must be a string). Properties accepting null are defined using nullable():

The array of all structure properties is returned by the getShape() method.

By default, no additional items can be present in the input data:

This can be changed using otherItems(). As a parameter, pass the schema to validate each extra item:

You can create a new structure by extending another using extend():

Array

An array with defined keys (since version 1.3.2). Everything that applies to structures applies to it.

Tuples: tuple()

A tuple is a fixed-size array where each position has its own schema (since version 1.4):

When configurations are layered, a later tuple replaces the earlier one wholesale - mixing positions of two tuples is never what you meant. Positions beyond the shape can be allowed with otherItems(), which describes the rest elements.

Unlike a structure, a tuple does not accept null as an empty value; write Expect::anyOf(Expect::tuple([...]), null) when the value may be missing entirely.

Deprecated Properties

You can mark a property as deprecated using the deprecated([string $message]) method. Information about deprecation is returned using $processor->getWarnings():

Description: description()

Any element can carry a human-readable description (since version 1.4). It has no effect on validation - the schema is often the only place where the meaning of a configuration option is written down at all, and description() is where you write it. It also travels into the JSON Schema export:

Ranges: min() max()

Use min() and max() to limit the count for arrays:

For strings, they limit the length:

For numbers, they limit the value:

Of course, it is possible to specify just min() or just max():

Regular Expressions: pattern()

Using pattern(), you can specify a regular expression that the entire input string must match (i.e. as if it were wrapped in ^ and $ characters):

A pattern belongs to strings, just like items() belongs to arrays. Attach either of them to an element of a different kind and Schema raises a deprecation notice instead of silently ignoring the constraint (since version 1.4).

Custom Assertions: assert()

You can add any other constraints using assert(callable $fn).

Or

You can add a custom description to each assertion. It will be part of the error message.

The method can be called repeatedly to add multiple constraints. It can be interleaved with calls to transform() and castTo().

Transformation: transform()

Successfully validated data can be modified using a custom function:

The method can be called repeatedly to add multiple transformations. It can be interleaved with calls to assert() and castTo(). The operations are performed in the order in which they are declared:

The transform() method can simultaneously transform and validate the value. This is often simpler and involves less code duplication than chaining transform() and assert(). For this purpose, the function receives a Nette\Schema\Context object with an addError() method, which can be used to add information about validation problems:

Casting: castTo()

Successfully validated data can be cast:

In addition to native PHP types, you can also cast to classes. It distinguishes between a simple class without a constructor and a class with a constructor. If the class has no constructor, an instance is created, and all structure elements are written to the properties:

If the class has a constructor, the structure elements are passed as named arguments to the constructor:

Casting combined with a scalar parameter creates an object and passes the value as the single argument to the constructor:

Normalization: before()

Before the validation itself, the data can be normalized using the before() method. As an example, let's take an element that must be an array of strings (e.g., ['a', 'b', 'c']), but accepts input in the form of string a b c:

The method can be called repeatedly (since version 1.4). The handlers are then chained, each receiving the result of the previous one:

Up to version 1.3, a second call to before() silently discarded the first one.

Mapping to Objects: from()

You can have the structure schema generated from a class. Example:

Anonymous classes are also supported:

Because the information obtained from the class definition may not be sufficient, you can supplement the elements with your own schema using the second parameter:

Merging Multiple Configurations

Applications often assemble their configuration in layers: there are built-in default values, and on top of them the user supplies their own settings, which should override only the items they actually specify. That is exactly what processMultiple() does - it takes several datasets, merges them in order so that later ones take precedence, and validates the final result as a whole:

The host item keeps its default value because the user did not set it, while port and logging are overwritten by the later dataset. Values stored under string keys are merged this way; numerically indexed items (lists) are appended one after another instead of being overwritten.

Exporting to JSON Schema

Your schema is already a precise description of what the configuration may contain, and that description is useful outside PHP as well. JsonSchema::export() (since version 1.4) turns it into a JSON Schema document, the format editors read to offer completion and underline mistakes directly in the JSON or YAML file:

The export describes the shape of the data: types, ranges, patterns, required items, enum values and the texts you added with description(). Default values, castTo() and transform() are deliberately left out - they describe what happens to the data once it has been validated, and JSON Schema has no way to say that.

For the same reason, a type that exists only in PHP - a class such as Expect::type(Address::class), a callable or a resource - throws Nette\NotSupportedException instead of producing a document that would quietly claim something else.

Under the Hood: normalize, merge, complete

Every schema element - whether built-in or one you write yourself - implements four methods that together define how it handles data. Three of them form the processing pipeline:

  1. normalize() - prepares the raw input. This is where before() hooks run and where, for example, an object is turned into an array. It runs first, separately on each dataset.
  2. merge() - combines two already normalized datasets, with the later one taking priority. This step is used only by processMultiple(); process() skips it, because it has just a single dataset.
  3. complete() - performs the actual validation, fills in default values for missing items, and applies assert(), transform() and castTo(). It runs last, on the merged result.

The fourth method, completeDefault(), is called by the parent element for an item entirely missing from the input - it either supplies the default value or reports that a required() item is missing.

So process() runs normalize → complete, while processMultiple() runs normalize (each dataset) → merge → complete. This order is why before() sees the raw input, whereas transform() sees the already validated value.

Custom Schema Elements

You can get a long way with assert(), transform() and before(), so you rarely need to build anything from scratch. But when you want a reusable, self-contained element with its own validation and merging logic, you can create one by implementing the Nette\Schema\Schema interface. It has exactly the four methods described above:

Errors are not thrown; instead you report them through the Nette\Schema\Context object using $context->addError() and return null. The Processor gathers all errors and throws them together at the end.

As an example, let's build a reusable element for byte sizes in the friendly notation people use in configuration files - '512kB', '2 MB' - which validates them and returns the number of bytes:

You can use it anywhere a built-in element is expected - on its own or as part of a larger structure:

Because the element implements the whole interface, it also works automatically inside processMultiple() - the Processor calls its merge() method just like for any other element.


All versions of schema with dependencies

PHP Build Version
Package Version
Requires php Version 8.1 - 8.5
nette/utils Version ^4.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package nette/schema contains the following files

Loading the files please wait ...