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() - returns true if the data was successfully validated
  • hasError() - returns true if the data was invalid
  • error() - returns ValidationError if the data was invalid, or null 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:

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 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.