Creating a new validator instance is easy, just instantiate the Opis\JsonSchema\Validator class.

use Opis\JsonSchema\Validator;

$validator = new Validator();

If you don’t need custom features (such as filters), you can use Opis\JsonSchema\CompliantValidator as validator. This ensures that you have enabled only the options officially supported by json-schema standard. To handpick what features you want enabled, see parser options.

use Opis\JsonSchema\CompliantValidator;

$validator = new CompliantValidator();

Data validation

To validate some data, we can use the validate method, which has the following signature:

public function validate(
    $data, 
    $schema, 
    ?array $globals = null,
    ?array $slots = null
): Opis\JsonSchema\ValidationResult
  • $data is the data you want to validate. See more info about data types
  • $schema the JSON schema to use. This can be:
    • a string representing an uri-reference or a json-encoded schema
    • an instance of Opis\JsonSchema\Schema or Opis\JsonSchema\Uri (note: to load schemas over the network, register a callable responsible for fetching the JSON.)
    • a boolean, or an object (stdClass)
  • $globals contains global variables
  • $slots injects slots

You should reuse the validator instance because the parsed schemas are cached.

Example

use Opis\JsonSchema\{
    Validator,
    ValidationResult,
    Helper,
};

$validator = new Validator();

// Global variables example
// We recommend to use uppercase letters for global variables
$globals = [
    'GLOBAL-A' => 'a',
    'GLOBAL-B' => 'b',
];

// Slots example
$slots = [
    'slot-1' => json_decode('{"type": "string"}', false),
    // You can also use uris to automatically resolve schemas
    'slot-2' => 'http://example.com/schema.json',
];

// Schema as URI example
$schema = 'http://example.com/schema.json';

// Schema as a JSON string example
$schema = <<<'JSON'
{
    "$id": "http://example.com/schema.json",
    
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
        }
    },
    "required": ["name"]
}
JSON;

// Schema as an stdClass object
$schema = (object) [
    '$id' => 'http://example.com/schema.json',
    'type' => 'object',
    'properties' => (object)[
        'name' => (object)[
            'type' => 'string',
            'minLength' => 1,
            'maxLength' => 100,
        ]
    ],
    'required' => ['name']
];

// Schema using toJSON() helper
// in 99.9% of cases you don't have to cast to object
// The helper cannot convert to object an empty php array

$schema = Helper::toJSON([
    '$id' => 'http://example.com/schema.json',
    'type' => 'object',
    'properties' => [
        'name' => [
            'type' => 'string',
            'minLength' => 1,
            'maxLength' => 100,
        ]
    ],
    'required' => ['name']
]);

// Example of data

// integer
$data = 123;
// number
$data = 123.5;
// string
$data = "opis";
// null
$data = null;
// boolean
$data = true; $data = false;
// array
$data = [1, 2, 3];
// object
$data = (object)['name' => 'opis'];
// decoding a JSON string
$data = json_decode('{"name": "opis"}');
// object (using helper)
$data = Helper::toJSON(['name' => 'opis']);

// Validation

/** @var ValidationResult\ $result */
$result = $validator->validate($data, $schema, $globals, $slots);

// Checking if $data is valid

if ($result->isValid()) {
    // Do something...
}

// Checking if there is an error
if ($result->hasError()) {
    // Get the error
    $error = $result->error();
}

Data types

The data you want to validate must NOT be provided as a JSON-encoded string, because then it will always be considered a string. Use the following table to map PHP types to JSON types.

PHP JSON
null null
bool / boolean boolean
int / integer integer or number
float / double number
string string
array (indexed - without keys) array
\stdClass object

If you have your data as a JSON encoded string, you can use json_decode function to decode it.

If you want to validate data from $_POST you can use a helper method to automatically convert associative arrays to objects - see example. However, we cannot distinguish an indexed array from an associative array when the array is empty, so you might need to manually apply a cast to object.

use Opis\JsonSchema\Helper;

$data = Helper::toJSON($_POST);

Max errors

You can set how many errors a keyword can generate. Default is 1.

$validator->setMaxErrors(5);

Not all keywords are interested in maxErrors, only the keywords that handle multiple sub-schema validations, such as properties.

Let’s see an example. Our schema is

{
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "minLength": 3
        },
        "age": {
            "type": "integer",
            "minimum": 18
        }
    }
}

and, our data is

{"name":  "ab", "age": 10}

Let’s set maxErrors to 1. The properties keyword will validate name property, and because there is an error, and the maxErrors is 1, no other validation occurs (age property is ignored here).

Example output

{
    "keyword": "properties",
    "message": "The properties must match schema: name",
    "subErrors": [
        {
            "keyword": "minLength",
            "message": "Minimum string length is 3, found 2"
        }
    ]
}

If the maxErrors is set to 5, then the age is also validated (because there are 4 errors left to check). The age property is invalid, so the properties keywords has now 2 sub-errors (and a max of 3 errors left to check).

Example output

{
    "keyword": "properties",
    "message": "The properties must match schema: name, age",
    "subErrors": [
        {
            "keyword": "minLength",
            "message": "Minimum string length is 3, found 2"
        },
        {
            "keyword": "minimum",
            "message": "Number must be greater than or equal to 18"
        }
    ]
}

Stop at first error

When validating objects the process stops at first error. This can be changed since v2.4.0.

$validator->setStopAtFirstError(false);

Here is an example:

use Opis\JsonSchema\{
    Validator,
    ValidationResult,
    Errors\ErrorFormatter,
};

$schema = <<<'JSON'
{
  "type": "object",
  "properties": {
    "value": {
      "type": "string",
      "minLength": 10,
      "pattern": "^a"
    }
  }
}
JSON;

$data = (object)[
    "value" => "b",
];

$validator = new Validator();
$validator->setMaxErrors(10);
$validator->setStopAtFirstError(false);

/** @var ValidationResult $result */
$result = $validator->validate($data, $schema);

if ($result->isValid()) {
    echo "Valid";
} else {
    echo json_encode(
        (new ErrorFormatter())->format($result->error()),
        JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
    );
}

The above example will output two errors for the same property.

{
    "/value": [
        "Minimum string length is 10, found 1",
        "The string should match pattern: ^a"
    ]
}

Exceptions

If you want to catch exceptions thrown by opis/json-schema you should catch instances of Opis\JsonSchema\Exceptions\SchemaException.

use Opis\JsonSchema\Exceptions\SchemaException;

try {
    $result = $validator->validate($data, $schema);
} catch (SchemaException $e) {
    // ...
}
Exception Description
UnresolvedReferenceException Cannot resolve an uri-reference or a json pointer.
UnresolvedFilterException Filter is not registered.
UnresolvedContentEncodingException Content encoding is not registered.
UnresolvedContentMediaTypeException Media type is not registered.
ParseException Schema cannot be parsed.
InvalidKeywordException Some keyword contains invalid value.
InvalidPragmaException Some pragma keyword contains invalid value.
DuplicateSchemaIdException Schema contains duplicates for $id keyword (after resolving to base).