Otar Chekurishvili just opened the Opt-in JSON Comments and Trailing Commas RFC for PHP 8.7. It adds two flags that let json_decode() and json_validate() read JSON with comments in it, and with a comma after the last item in a list. Strict JSON stays the default.
A lot of tools keep their config in JSON files that people edit by hand, and people want to leave a comment explaining a setting. Today json_decode() rejects those with an error. Some projects get around this with a parser, or with a regular expression that strips comments first but that can be brittle.
What It Does
The RFC adds two constants:
JSON_ALLOW_COMMENTSaccepts//line comments and/* */block comments.JSON_ALLOW_TRAILING_COMMASaccepts one comma after the last item of a non-empty array or object.
Here is the RFC's own example:
$config = <<<'JSON' { // Connection for local development "host": "localhost", "port": 5432, /* default PostgreSQL port */ "options": [ "persistent", "utf8", ], } JSON; $data = json_decode($config, true, flags: JSON_ALLOW_COMMENTS | JSON_ALLOW_TRAILING_COMMAS); // ['host' => 'localhost', 'port' => 5432, 'options' => ['persistent', 'utf8']] $data = json_decode($config, true); // NULL, json_last_error_msg(): "Syntax error near location 2:5"
The flags are independent, so you can turn on comments and still reject trailing commas. The parser throws the comments away, and comment markers inside a string are left alone, so "https://example.com/*" stays a normal string. That's the case a comment-stripping regex tends to break. Error locations also still point at the right line of the original file.
json_encode() doesn't change. It never writes comments or trailing commas.
What It Doesn't Do
This isn't JSON5. JSON5 also adds single-quoted strings, unquoted keys, hex numbers, NaN and Infinity, and the RFC leaves all of that out. Both flags together match JWCC (JSON With Commas and Comments), the format Tailscale uses in Go under the name HuJSON.
The RFC also skips # comments, nested block comments, and more than one trailing comma, so [1,,] is still a syntax error.
Why Two Flags
In the pre-RFC thread, Tim Düsterhus suggested a single JSON_ALLOW_JSONC flag. The RFC turns that down. The JSONC spec is still a draft, and it makes trailing commas optional, so one flag can't point at it for a fixed meaning. Chromium, RapidJSON, Jackson and .NET all use a separate setting for each feature too.
Düsterhus replied in the discussion thread that he's "not happy, but the rejected is well-argued," and called the RFC "incredibly well-written." Larry Garfield agreed:
This is a very tight RFC, and I have no remaining objections to it. Nicely done!
What It Means for Your Code
Code that doesn't pass the new flags gets the same results, errors and error positions as before. The RFC backs that up with a differential test over 120,025 inputs that found no difference. In the RFC's benchmark, parsing strict JSON costs about 1.6 to 1.7% more CPU instructions. The RFC lists two scanner changes that would bring that down to about 0.6%.
There are a few small breaks to know about:
- Code that defines its own global
JSON_ALLOW_COMMENTSorJSON_ALLOW_TRAILING_COMMASconstant gets a warning and the built-in value. json_decode()ignores unknown flag bits today. Code that passes bit 23 or 24 by mistake would start accepting comments or trailing commas.- The
ValueErrormessage fromjson_validate()for a bad flag now names all three accepted flags.
If you maintain a package that supports older PHP versions, you can check PHP_VERSION_ID >= 80700 and keep your userland parser as the fallback.
What Happens Next
The RFC is Under Discussion, and the php-src implementation is open. There are two primary votes, one per flag, and each needs a 2/3 majority. No vote date is set yet.
Read the full proposal in the RFC on the PHP wiki, and follow its status on the PHP News RFC tracker.