====== PHP RFC: JSON Schema validation support ======
* Version: 0.1
* Date: 2025-06-15
* Author: Jakub Zelenka, bukka@php.net
* Status: Draft
===== Introduction =====
The json extension does not offer any way of structural validation of the content except basic
syntax checking. Being able to validate the actual structure is very useful in many ways and
it has been requested many times.
The [[https://json-schema.org/|JSON Schema]] became a primary method of validation the JSON
and has been widely adopted. As such PHP would benefit from having that support in JSON extenions.
===== Proposal =====
The proposal is to add support JSON Schema to JSON extension. Specifically, it adds support to
json_decode and json_validate. This is done as an additional argument that accepts schema object.
The object can be created from string. The error handling is consistent with the current handling.
==== API ====
The proposal introduces a new class JsonSchema that can be created only using static method
createFromString. It also introduces a new exception class JsonSchemaException that is a subclass
of JsonException. The API stub is following:
In addition, a set of new error constants is introduced. These codes are either used as exception
codes or global error codes. This means it follows the current error handling in the JSON extension.
===== Backward Incompatible Changes =====
None
===== Proposed PHP Version(s) =====
PHP 8.5
===== Future Scope =====
The significant effort to develop the whole library for JSON Schema wasn't just to introduce
verification. The main motivation was about what this might allow, primarily the ability to map
JSON data to specific PHP classes and the ability to do early parsing termination, thus potentially
eliminating hash DoS attacks. Specifically, the following features might be considered:
* Support for default draft selection to allow schemas without the $schema tag (technically not compliant to the spec)
* Complete support for all drafts
* Early validation failure if it is certain that an instance will be invalid (this is actually not that simple due to composition, but it is doable)
* Special new schema keyword to specify mapping class for objects and subsequent mapping into them (native hydration)
* New creation functions like createFromArray and possibly createFromClass (possibility to automatically generate schema from class and attributes)
* Better error reporting (location of the error)
* Optional validation of some formats
* Exposing JSON pointer to user space (e.g., JsonPointer class)
The above list contains more ideas that might be proposed, but each of them will, of course, require
a separate RFC. There are more things that can be done as well. In addition to the schema-specific
parts, the plan is to also look into the introduction of a new SIMD parser that would live in jso and could
be used by the json extension. That could result in significant performance gains.
===== Proposed Voting Choices =====
As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted.
* Yes
* No
The vote started on 2025-07-DD at mm:hh UTC and ends on 2015-07-DD at mm:hh UTC.
===== Patches and Tests =====
A working implementation has been added to jsond and can be seen at
https://github.com/bukka/php-jsond/tree/next. The jsond extension is almost the same as the json
extension with some minor changes and different naming. This means that pretty much the same
implementation can be added to the json extension.
The actual schema integration is done using my jso library that can be found at
https://github.com/bukka/jso. This is an independent library initially developed for testing the
json parser before it was migrated to jsond and later became the current implementation of the
json extension. The development of JSON schema validation started a few years ago and has
stabilized over time. There is still ongoing development to support more drafts. The current
status is almost complete draft 4 and 6 support. Draft 7 support is coming soon. Other drafts
might be available before the PHP RC1 version. The reason the development is separated is the
possibility of introducing unit tests and specifically tailored integration tests. It is also
much easier to debug and verify issues as well as experiment with new features.
The library is bundled and there is a sync script to synchronize the jso additions. The library
allows specific virtual header overrides for virtual types. This means that it can effectively wrap
internal PHP types and does not need to do extra copying to process the verified instances. The
plan is to synchronize the release cycle of the library so it has stable branches that can be
tracked by PHP branches.
===== Implementation =====
After the project is implemented, this section will contain
- the version(s) it was merged to
- a link to the git commit(s)