Migration
Migrating from 1.x to 2.0
Since 2.0 is a major version release, breaking changes are expected. These changes affect only the PHP part, you don’t have to rewrite your JSON schemas.
Validator
In 1.x there were 3 methods to validate a schema: dataValidation, uriValidation, and schemaValidation.
In 2.0 you should use the validate method, which is smart enough to detect
what kind of validation are you doing. This method returns a ValidationResult
.
The above 3 methods are still present in 2.0, but they return a ValidationError
for invalid data,
or null
if data is valid. We recommend sticking to validate
method.
use Opis\JsonSchema\{
Validator,
Helper,
};
$validator = new Validator();
// Data validation
$schema = Helper::toJSON([
'type' => 'array',
'items' => [
'type' => 'integer'
]
]);
$result = $validator->validate([5, 6, 7], $schema);
// Uri validation
$result = $validator->validate(
"some data",
"http://example.com/schema.json"
);
// Schema validation
// We cannot create a schema directly,
// it must be parsed first.
$schema = $validator
->loader()
->loadObjectSchema((object)['type' => 'string']);
$result = $validator->schemaValidation("some data", $schema);
use Opis\JsonSchema\{
Validator,
Schema
};
$validator = new Validator();
// Data validation
$schema = (object) [
'type' => 'array',
'items' => (object) [
'type' => 'integer'
]
];
$result = $validator->dataValidation([5, 6, 7], $schema);
// Uri validation
$result = $validator->uriValidation(
"some data",
"http://example.com/schema.json"
);
// Schema validation
$schema = Schema::fromJsonString('{"type": "string"}');
$result = $validator->schemaValidation("some data", $schema);
ValidationResult
The validation result indicates the validity of the data, and also provides the error. This class contains only 3 methods:
isValid()
- returnstrue
if the data was successfully validatedhasError()
- returnstrue
if the data was invaliderror()
- returnsValidationError
if the data was invalid, ornull
if the data was valid
Version 2.0 also brings a few methods to format error messages.
if ($result->isValid()) {
// Valid ...
}
if ($result->hasError()) {
// Get the error (there is only one error)
$error = $result->error();
}
if ($result->isValid()) {
// Valid ...
}
if ($result->hasErrors()) {
// Get first error
$error = $result->getFirstError();
}
Schema loader
In 1.x the schema loader was used only to resolve an uri to a schema. Starting with 2.0, the following were added to the loader:
- a schema resolver, that resolves schema content using an uri
- a schema parser, to handle the keywords and various resolvers
Opis\JsonSchema\Loaders\Memory
and Opis\JsonSchema\Loaders\File
resolvers were merged into one powerful resolver.
Now, you should use the default resolver Opis\JsonSchema\Resolvers\SchemaResolver
:
- use registerRaw - to replace the 1.x Memory loader
- use registerFile or registerPrefix - to replace the 1.x File loader
use Opis\JsonSchema\Validator;
$validator = new Validator();
$validator->resolver()->registerPrefix(
"/path/to/schemas",
"http://example.com/"
);
$result = $validator->validate(
"some data",
"http://example.com/my-schema.json"
);
use Opis\JsonSchema\Validator;
$validator = new Validator();
$loader = new \Opis\JsonSchema\Loaders\File(
"http://example.com/",
["/path/to/schemas"]
);
$result = $validator->uriValidation(
"some data",
"http://example.com/my-schema.json"
);
If you ever extend the Opis\JsonSchema\Resolvers\SchemaResolver
class, you must set the new resolver
use Opis\JsonSchema\{
Validator,
SchemaLoader,
};
use Opis\JsonSchema\Resolvers\SchemaResolver;
class MySchemaResolver extends SchemaResolver {
// ...
}
$validator = new Validator(
new SchemaLoader(null, new MySchemaResolver())
);
// Or
$validator = new Validator();
$validator->loader()->setResolver(new MySchemaResolver());
Filters
In 2.0 filters can also be callables. For more info, please check custom filters page.
$modulo_filter = function (int $value, array $args): bool {
$divisor = $args['divisor'] ?? 1;
$reminder = $args['reminder'] ?? 0;
return $value % $divisor == $reminder;
};
use Opis\JsonSchema\IFilter;
class ModuloFilter implements IFilter
{
public function validate($value, array $args): bool {
$divisor = $args['divisor'] ?? 1;
$reminder = $args['reminder'] ?? 0;
return $value % $divisor == $reminder;
}
}
Registering a filter
use Opis\JsonSchema\Validator;
use Opis\JsonSchema\Resolvers\FilterResolver;
$validator = new Validator();
/** @var FilterResolver $filters */
$filters = $validator->parser()->getFilterResolver();
$modulo = function (int $value, array $args): bool {
$divisor = $args['divisor'] ?? 1;
$reminder = $args['reminder'] ?? 0;
return $value % $divisor == $reminder;
};
// Register our modulo filter
$filters->registerCallable("integer", "modulo", $modulo);
use Opis\JsonSchema\{
Validator,
FilterContainer
};
// Create a new FilterContainer
$filters = new FilterContainer();
// Register our modulo filter
// Class ModuleFilter is defined in the above example
$filters->add("integer", "modulo", new ModuloFilter());
// Create a validator
$validator = new Validator();
// Set filters to be used by validator
$validator->setFilters($filters);
Formats
In 2.0 formats can also be callables. For more info, please check custom formats page.
$prime_number = function (int $data): bool {
if ($data < 2) {
return false;
}
if ($data == 2) {
return true;
}
$max = floor(sqrt($data)) + 1;
for ($i = 3; $i < $max; $i += 2) {
if ($data % $i == 0) {
return false;
}
}
return true;
};
use Opis\JsonSchema\IFormat;
class PrimeNumberFormat implements IFormat
{
public function validate($data): bool {
if ($data < 2) {
return false;
}
if ($data == 2) {
return true;
}
$max = floor(sqrt($data)) + 1;
for ($i = 3; $i < $max; $i += 2) {
if ($data % $i == 0) {
return false;
}
}
return true;
}
}
Registering a format
use Opis\JsonSchema\Validator;
use Opis\JsonSchema\Resolvers\FormatResolver;
$validator = new Validator();
/** @var FormatResolver $formats */
$formats = $validator->parser()->getFormatResolver();
// Register our prime number format
$formats->registerCallable("integer", "prime", function (int $value): bool {
// See the example above for the function contents
});
use Opis\JsonSchema\{
Validator,
FormatContainer
};
// Create a new FormatContainer
$formats = new FormatContainer();
// Register our prime format
// Class PrimeNumberFormat is defined in the above example
$formats->add("integer", "prime", new PrimeNumberFormat());
// Create a IValidator
$validator = new Validator();
// Set formats to be used by validator
$validator->setFormats($formats);
Media types
Starting with 2.0 we added a fallback mechanism that uses finfo
to auto-detect
the media type of the content.
For more info, please check custom media types page.
In draft-2020-12 and draft-2019-09 the contentMediaType
keyword
is disabled by default.
You can enable it by setting the decodeContent
option.
Content encodings
In 2.0 you can add your custom content encodings. For more info, please check custom content encodings page.
In draft-2020-12 and draft-2019-09 the contentEncoding
keyword
is disabled by default.
You can enable it by setting the decodeContent
option.