# [RFC] JSON Schema validation support

- Thread: https://externals.io/message/127881
- Original archive: https://news-web.php.net/php.internals/127881
- Started by Jakub Zelenka on 2025-07-04T21:01:20+00:00
- Messages: 14
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #127881 — Jakub Zelenka — 2025-07-04T21:01:20+00:00

URL: https://externals.io/message/127881#127881

Hello,

I would like introduce and open discussion for RFC proposing the addition
of JSON Schema validation support to JSON extension:

https://wiki.php.net/rfc/json_schema_validation

If this is successful, it should be just the first for further improvements
(see the future scope).

Kind regards,

Jakub

---

## #127883 — Valentin Udaltsov — 2025-07-04T21:49:38+00:00

URL: https://externals.io/message/127881#127883 · In reply to: #127881

> Hello,
>
> I would like introduce and open discussion for RFC proposing the addition
> of JSON Schema validation support to JSON extension:
>
> https://wiki.php.net/rfc/json_schema_validation
>
> If this is successful, it should be just the first for further
> improvements (see the future scope).
>
> Kind regards,
>
> Jakub
>

Hi, Jakub!

I like the idea. I have a couple of initial thoughts:

1. Wouldn't it make sense to place all the new classes under the `Json`
namespace, similar to how it’s done in `ext-random`?
2. If there’s no way to interact with the `JsonSchema` class, what purpose
does it serve? Wouldn’t it be simpler to just extend `json_decode()` with
an optional `?string $schema = null` parameter?

-- 
Kind regards,
Valentin

---

## #127886 — Jakub Zelenka — 2025-07-04T22:11:25+00:00

URL: https://externals.io/message/127881#127886 · In reply to: #127883

Hi,

On Fri, Jul 4, 2025 at 11:49 PM Valentin Udaltsov <
udaltsov.valentin@gmail.com> wrote:

> 
>
> > […]
>
> Hi, Jakub!
>
> I like the idea. I have a couple of initial thoughts:
>
> 1. Wouldn't it make sense to place all the new classes under the `Json`
> namespace, similar to how it’s done in `ext-random`?
>

This would be widely inconsistent with the current interface / exception
class in the extension. The ext-random was a new extension so it's a
completely different case. I think it makes much more sense to keep the
extension consistent than introducing new interface.


> 2. If there’s no way to interact with the `JsonSchema` class, what purpose
> does it serve? Wouldn’t it be simpler to just extend `json_decode()` with
> an optional `?string $schema = null` parameter?
>

There are couple of reasons for this:

- It allows re-using the same parsed schema without a need to parse it
multiple times for each decoding / validation - the class internally holds
parsed representation of the schema.
- We might want to introduce additional flags that will impact the parsing
(e.g. default version)
- It might allow a way to better cache schema between requests so it could
further improve performance in the future
- It will allow the possibility to get schema from other sources than
string - e.g. from PHP array or even automatic creation from the class
(that's why the JsonSchema is created using static method and not using
constructor). This might be especially useful for object mapping.

Kind regards,

Jakub

---

## #127895 — Ben Ramsey — 2025-07-04T23:07:43+00:00

URL: https://externals.io/message/127881#127895 · In reply to: #127881

> 
> 
> Hello,
> 
> I would like introduce and open discussion for RFC proposing the addition of JSON Schema validation support to JSON extension:
> 
> https://wiki.php.net/rfc/json_schema_validation
> 
> If this is successful, it should be just the first for further improvements (see the future scope).
> 
> Kind regards,
> 
> Jakub


There are 9 versions of JSON Schema and 11 Internet-Drafts, all of which have expired. Many of these versions are still widely used in the wild (draft-04, draft-05, and draft-06 come to mind as heavily used, despite several newer versions).

Which version do you plan to target with this RFC, or will it be able to parse all versions, depending on what the input has specified in the `$schema` properties? I’ve even seen multiple schema versions used within the same set of referenced documents, and as long as the parser knows how to handle all versions, it will parse things just fine.

For the reference of others on the list, here’s what I mean by 9 versions and 11 I-Ds:

* Version: 2020-12
  - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01
  - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00

* Version: 2019-09
  - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02

* Version: draft-07
  - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01
  - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-00

* Version: draft-06
  - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-01

* Version: draft-05
  - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-00

* Version: draft-04
  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04

* Version: draft-03
  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-03

* Version: draft-02
  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-02

* Version: draft-01
  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-01

Typically, when you create a JSON Schema document, you specify the `$schema` property, the value of which is a URI that refers to the schema version you’re using, like this:

```
{
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
```

This lets the parser know what “flavor” of JSON Schema you’re using. The problem is that many parsers don’t understand all schema versions, and the most popular one in PHP (justinrainbow/json-schema <https://packagist.org/packages/justinrainbow/json-schema>) only supports draft-03 and draft-04, both well over 12 years old, at this point.

Perhaps the JSON Schema library that is most robust and supports the latest versions is the opis/json-schema package <https://opis.io/json-schema/2.x/>. It supports draft-06, draft-07, 2019-09, and 2020-12, which is pretty much all the newer ones that justinrainbow/json-schema doesn’t support.

I think your RFC needs to address all these versions and how you plan to address compatibility issues between them all.

Since all the I-Ds have expired without a formal IETF RFC being voted on and passing, you should probably call attention to the fact that JSON Schema, while not moving much right now, is still a moving target and any new versions will require updates to the core to support them.

Cheers,
Ben

---

## #127896 — Ben Ramsey — 2025-07-04T23:27:06+00:00

URL: https://externals.io/message/127881#127896 · In reply to: #127895

> 
> 
> > […]
> 
> 
> There are 9 versions of JSON Schema and 11 Internet-Drafts, all of which have expired. Many of these versions are still widely used in the wild (draft-04, draft-05, and draft-06 come to mind as heavily used, despite several newer versions).
> 
> Which version do you plan to target with this RFC, or will it be able to parse all versions, depending on what the input has specified in the `$schema` properties? I’ve even seen multiple schema versions used within the same set of referenced documents, and as long as the parser knows how to handle all versions, it will parse things just fine.
> 
> For the reference of others on the list, here’s what I mean by 9 versions and 11 I-Ds:
> 
> * Version: 2020-12
>  - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01
>  - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00
> 
> * Version: 2019-09
>  - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02
> 
> * Version: draft-07
>  - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01
>  - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-00
> 
> * Version: draft-06
>  - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-01
> 
> * Version: draft-05
>  - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-00
> 
> * Version: draft-04
>  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04
> 
> * Version: draft-03
>  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-03
> 
> * Version: draft-02
>  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-02
> 
> * Version: draft-01
>  - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-01
> 
> Typically, when you create a JSON Schema document, you specify the `$schema` property, the value of which is a URI that refers to the schema version you’re using, like this:
> 
> ```
> {
>  "$schema": "https://json-schema.org/draft/2020-12/schema"
> }
> ```
> 
> This lets the parser know what “flavor” of JSON Schema you’re using. The problem is that many parsers don’t understand all schema versions, and the most popular one in PHP (justinrainbow/json-schema <https://packagist.org/packages/justinrainbow/json-schema>) only supports draft-03 and draft-04, both well over 12 years old, at this point.
> 
> Perhaps the JSON Schema library that is most robust and supports the latest versions is the opis/json-schema package <https://opis.io/json-schema/2.x/>. It supports draft-06, draft-07, 2019-09, and 2020-12, which is pretty much all the newer ones that justinrainbow/json-schema doesn’t support.
> 
> I think your RFC needs to address all these versions and how you plan to address compatibility issues between them all.
> 
> Since all the I-Ds have expired without a formal IETF RFC being voted on and passing, you should probably call attention to the fact that JSON Schema, while not moving much right now, is still a moving target and any new versions will require updates to the core to support them.
> 
> Cheers,
> Ben


Another thing that needs to be addressed in the RFC is how error reporting will work. I see this hinted at under Future Scope, but one of the benefits of the existing JSON Schema Composer packages is the robust level of error reporting they provide.

I think robust error reporting is base-level functionality and non-optional for a minimum viable feature. I won’t have a reason to use the built-in JSON Schema functionality until it has a certain level of error reporting that goes well beyond simple `JSON_ERROR_SCHEMA_*` error codes.

I see that the JSO C library supports JSON Schema validation for draft-04 and draft-06. IMO, you will need at least 2020-12 support, since this is the version that OpenAPI 3 has adopted, and any tooling for it will require support for parsing 2020-12 schemas.

Cheers,
Ben

---

## #127897 — Jakub Zelenka — 2025-07-04T23:30:02+00:00

URL: https://externals.io/message/127881#127897 · In reply to: #127895

Hi



> There are 9 versions of JSON Schema and 11 Internet-Drafts, all of which
> have expired. Many of these versions are still widely used in the wild
> (draft-04, draft-05, and draft-06 come to mind as heavily used, despite
> several newer versions).
>
> Which version do you plan to target with this RFC, or will it be able to
> parse all versions, depending on what the input has specified in the
> `$schema` properties?
>

This is noted in the implementation section:

> The current status is almost complete draft 4 and 6 support. Draft 7
support is coming soon.

By almost I mean that it needs to implement dependencies (which I plan to
sort out before this goes to vote) and it didn't go through complete
regression pack which should happen before the first RC. Draft 7 is pretty
much just "if" so it should be supported as well as it's pretty similar
to dependencies. I will see about other drafts if they could make it to 8.5
but the plan to support eventually all. I will make it a bit clearer in the
RFC. Technically this is more library implementation thing but as it's
bundled it should be properly noted in the RFC as well.


>
> I think your RFC needs to address all these versions and how you plan to
> address compatibility issues between them all.
>
>
All drafts except 4 require $schema to be there so it's the way how to
currently select the version. The future scope actually lists the default
draft for schemas without $schema so it could be selected by users. We
could maybe look into some auto-identification in the future but again it
would be the future scope. I will add some note about it to the RFC.

Since all the I-Ds have expired without a formal IETF RFC being voted on
> and passing, you should probably call attention to the fact that JSON
> Schema, while not moving much right now, is still a moving target and any
> new versions will require updates to the core to support them.
>

Yeah good point I should mention that new version will be treated as
features.

Cheers

Jakub

---

## #127898 — Jakub Zelenka — 2025-07-04T23:41:27+00:00

URL: https://externals.io/message/127881#127898 · In reply to: #127896

> Another thing that needs to be addressed in the RFC is how error reporting
> will work. I see this hinted at under Future Scope, but one of the benefits
> of the existing JSON Schema Composer packages is the robust level of error
> reporting they provide.
>
>
The error reporting is done using normal error codes and exceptions get
some sort of identification message. It doesn't collect multiple errors
with exact pointers to the place in the same way as the current JSON parser
doesn't do that - this is just how things are in the JSON extension and
this doesn't try to address all problems in one go - it basically needs
some extra parser context for this which is not there yet.


> I think robust error reporting is base-level functionality and
> non-optional for a minimum viable feature. I won’t have a reason to use the
> built-in JSON Schema functionality until it has a certain level of error
> reporting that goes well beyond simple `JSON_ERROR_SCHEMA_*` error codes.
>
>
Well you don't have to use it from the start. The reason for introduction
in this form is to mainly get something that we can build on. It is also
important to know that it makes sense to spend more time on it. It already
required lots of time to implement.

If we used the same standard on the json parser, we would never have json
extension in PHP because the error reporting does not provide complete info.


> I see that the JSO C library supports JSON Schema validation for draft-04
> and draft-06. IMO, you will need at least 2020-12 support, since this is
> the version that OpenAPI 3 has adopted, and any tooling for it will require
> support for parsing 2020-12 schemas.
>

None of the implementations started with support for all drafts from the
start. We will eventually support all but I don't see why that would have
to be done from the beginning.

Kind regards,

Jakub

---

## #127899 — Jakub Zelenka — 2025-07-04T23:47:32+00:00

URL: https://externals.io/message/127881#127899 · In reply to: #127898

> 
>
> > […]
> The error reporting is done using normal error codes and exceptions get
> some sort of identification message.
>

I should probably show some example how this looks like. See this test
https://github.com/bukka/php-jsond/blob/1f640becf3cd0f0cca9c72fa5045c7ccefc26d7f/tests/jsond_decode_schema_002.phpt


Kind regards,

Jakub

---

## #128168 — Jakub Zelenka — 2025-07-21T18:39:07+00:00

URL: https://externals.io/message/127881#128168 · In reply to: #127881

> Hello,
>
> I would like introduce and open discussion for RFC proposing the addition
> of JSON Schema validation support to JSON extension:
>
> https://wiki.php.net/rfc/json_schema_validation
>
> If this is successful, it should be just the first for further
> improvements (see the future scope).
>

I have done some updates to the RFC and I decided to target 8.6 as there is
not enough time to get to the state where I would be fully confident that
all edge cases are handled and it cannot crash. Basically I need to also
integrate full regression pack into it to be sure that all is good. As it
was also pointed out, having just few drafts supported could be quite
disappointing for users so the plan is to support all the latest drafts as
well from the beginning. This is more an implementation detail though so I
plan to open vote some time soon (after the feature freeze) to make sure
that the API is acceptable and I can just concentrate on getting the
implementation done.

Kind regards,

Jakub

---

## #128194 — Alexandre Daubois — 2025-07-23T14:06:41+00:00

URL: https://externals.io/message/127881#128194 · In reply to: #127881

Hi Jakub

Le mer. 23 juil. 2025 à 15:33, Jakub Zelenka <bukka@php.net> a écrit :
>
> Hello,
>
> I would like introduce and open discussion for RFC proposing the addition of JSON Schema validation support to JSON extension:
>
> https://wiki.php.net/rfc/json_schema_validation
>
> If this is successful, it should be just the first for further improvements (see the future scope).
>
> Kind regards,
>
> Jakub

Thank you for proposing such a feature! I personally really like it
and would be glad to see this land into PHP.
I think it would be even more useful if JsonSchema offers more ways to
load a schema. Schemas are often either remotely stored or stored in a
file.
It would be great to add two new factory methods:
JsonSchema::fromUri() and JsonSchema::fromFile(). Maybe
JsonSchema::createFromString() should also be renamed to fromString()
to be consistent with the recent additions to XMLReader.

Best,
Alex

---

## #128198 — Jakub Zelenka — 2025-07-23T15:41:47+00:00

URL: https://externals.io/message/127881#128198

Hi Alex,

On Wed, Jul 23, 2025 at 3:57 PM Alexandre Daubois <
alex.daubois+php@gmail.com> wrote:

> Thank you for proposing such a feature! I personally really like it
> and would be glad to see this land into PHP.
> I think it would be even more useful if JsonSchema offers more ways to
> load a schema. Schemas are often either remotely stored or stored in a
> file.
>

 Yes, this is exactly the reason why it's using a static method and not a
constructor

It would be great to add two new factory methods:
> JsonSchema::fromUri() and JsonSchema::fromFile().


Yeah something like this is planned in the next stage. In addition it could
be useful to create it from array or from class (sort of auto generate
schema) as well but that's all feature scope.


> Maybe
> JsonSchema::createFromString() should also be renamed to fromString()
> to be consistent with the recent additions to XMLReader.
>

 I actually took that name from recently
introduced HTMLDocument::createFromString and XMLDocument::createFromString
. So not sure what is more consistent. Personally I don't really mind.

Kind regards

Jakub

---

## #128202 — Alexandre Daubois — 2025-07-24T06:51:19+00:00

URL: https://externals.io/message/127881#128202 · In reply to: #128198

Hi Jakub,

Le mer. 23 juil. 2025 à 17:41, Jakub Zelenka <bukka@php.net> a écrit :
> In addition it could be useful to create it from array or from class (sort of auto generate schema)

Writing schema by hand is painful, so that would be amazing to see
this feature land one day.

>  I actually took that name from recently introduced HTMLDocument::createFromString and XMLDocument::createFromString . So not sure what is more consistent. Personally I don't really mind.

Indeed, a quick search in the code showed that in both cases, it seems
there's only one or two occurrences for each. Let's keep it as-is
then.

Best,
Alex

---

## #128203 — Niels Dossche — 2025-07-24T07:15:55+00:00

URL: https://externals.io/message/127881#128203 · In reply to: #128202

> 
> Indeed, a quick search in the code showed that in both cases, it seems
> there's only one or two occurrences for each. Let's keep it as-is
> then.

The context for XMLReader & XMLWriter is also a bit different.
"create" is not in the name because you're not actually creating anything yet, you're reading/writing from a string, from a stream, ...
Hence it's read as "XML Writer From String", etc. Whereas for Dom\*, it's actually creating the document already.

Kind regards
Niels

---

## #128216 — Larry Garfield — 2025-07-24T14:08:49+00:00

URL: https://externals.io/message/127881#128216 · In reply to: #128202

> Hi Jakub,
>
> Le mer. 23 juil. 2025 à 17:41, Jakub Zelenka <bukka@php.net> a écrit :
> > […]
>
> Writing schema by hand is painful, so that would be amazing to see
> this feature land one day.

I've done a little class <--> schema translation work in the past; this is much harder than it sounds. :-)  JSON Schema is considerably more complex/robust than PHP classes, so translating between the two is a challenge.  (Maybe set hooks could cover some cases now? Hm.)  Class->schema would be easier, but in that case I think it would be better to either leave to user-space (it would just be a bit of reflection work) or if it's in the core API to make it a separate operation from schema validation.  It's simple enough for a user to plug those two operations together themselves when appropriate.

--Larry Garfield
