This is an old revision of the document!
PHP RFC: json_validate
- Version: 0.9
- Date: 2022-08-14
- Author: Juan Carlos Morales, dev.juan.morales@gmail.com
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/json_validate
- Implementation: https://github.com/php/php-src/pull/9399
Introduction
This RFC introduces a new function called json_validate() to validate if an string contains a valid json.
Most userland implementations use json_decode() which by design generates a ZVAL(object/array/etc.) while parsing the string, ergo using memory and processing that could be save.
Proposal
Description
json_validate(string $json, int $depth = 512, int $flags = 0): bool
Parameters
json
The json string being analyzed.
This function only works with UTF-8 encoded strings.
Note:
PHP implements a superset of JSON as specified in the original » RFC 7159.
depth
Maximum nesting depth of the structure being decoded.
flags
Bitmask of JSON_INVALID_UTF8_IGNORE. The behavior of this constant is described on the JSON constants page.
Return values
Returns true if the string passed contains a valid json, otherwise returns false.
Examples
1. Validate a valid json-string
var_dump(json_validate('{ "test": { "foo": "bar" } }'));
Result will be
bool(true)
2. Validate an invalid json-string
var_dump(json_validate('{ "": "": "" } }'));
Result will be
bool(false)
Errors during validation can be fetch by using json_last_error() and/or json_last_error_msg().
Reasons to have **json_validate()** function in the core
Disadvantages of using json_decode to only validate a json-string
By design, json_decode() generates a ZVAL (object/array/etc.) while parsing the string, ergo using memory and processing for it, that is not needed if the only thing to discover is if a string contains a valid json or not.
Disadvantages of using regex
Using a regex for this task forces different, error-prone, hard to maintain, implementations.
Disadvantages of userland solutions
- Writing a JSON parser is no trivial
- They need to be up-to-date with the existing PHP JSON parser used by json_decode() already, otherwise a json-string valid in json_validate() might not be valid json-string for json_decode() or vice-versa.
- We already have a JSON parser in PHP, that is used by json_decode(); reusing the existing JSON Parser provides 100% compatibility between the validation of a json-string, and json_decode().
Needs from major projects and developers
In the “References” section, there is a list of major open-source php projects that could benefit with this new function.
Also in the mentioned section a link to one of the most popular StackOverflow questions is provided, which somehow reflects the need from our developers to have a feature like this included.
Please check the “References” section.
Complexity added in the core
At the moment, there is a JSON parser in the core, used by json_decode to do its job, so there is no need to write a new JSON parser for this RFC; the proposed function will use the existing JSON parser exclusively to parse an string without generating any object/array/etc. in memory for it.
Backward Incompatible Changes
None, as this is a new function only.
json_validate will no longer be available as a function name.
Proposed PHP Version(s)
next PHP 8.x
RFC Impact
This RFC has no impact on SAPIs, existing extensions, Opcache, etc.
Open Issues
- No open issues
Future Scope
- (To be defined by future discussions if needed)
Proposed Voting Choices
- (To be defined)
Implementation
- Github: https://github.com/php/php-src/pull/9399
References
Major Open-Source projects that will benefit out of this
class JsonValidator extends ConstraintValidator
public function validateJson($attribute, $value) { if (is_array($value)) { return false; } if (! is_scalar($value) && ! is_null($value) && ! method_exists($value, '__toString')) { return false; } json_decode($value); return json_last_error() === JSON_ERROR_NONE; }
public static function isJson($value) {
protected function isValidJsonValue($value) { if (in_array($value, ['null', 'false', '0', '""', '[]']) || (json_decode($value) !== null && json_last_error() === JSON_ERROR_NONE) ) { return true; } //JSON last error reset json_encode([]); return false; }
public function isValid($string) { if ($string !== false && $string !== null && $string !== '') { json_decode($string); if (json_last_error() === JSON_ERROR_NONE) { return true; } } return false; }
public static function validateJson($value, $params) { return (bool) (@json_decode($value)); }
final class Json extends AbstractRule { /** * {@inheritDoc} */ public function validate($input): bool { if (!is_string($input) || $input === '') { return false; } json_decode($input); return json_last_error() === JSON_ERROR_NONE; } }
final class Json extends AbstractRule { /** * {@inheritDoc} */ public function validate($input): bool { if (!is_string($input) || $input === '') { return false; } json_decode($input); return json_last_error() === JSON_ERROR_NONE; } }
public static function isJson($string) { json_decode($string); return json_last_error() == JSON_ERROR_NONE; }
function is_json( $argument, $ignore_scalars = true ) { if ( ! is_string( $argument ) || '' === $argument ) { return false; } if ( $ignore_scalars && ! in_array( $argument[0], [ '{', '[' ], true ) ) { return false; } json_decode( $argument, $assoc = true ); return json_last_error() === JSON_ERROR_NONE; }
if (\is_string($value)) { json_decode($value); //<------ HERE // Check if value is a valid JSON string. if ($value !== '' && json_last_error() !== JSON_ERROR_NONE) { /** * If the value is not empty and is not a valid JSON string, * it is most likely a custom field created in Joomla 3 and * the value is a string that contains the file name. */ if (is_file(JPATH_ROOT . '/' . $value)) { $value = '{"imagefile":"' . $value . '","alt_text":""}'; } else { $value = ''; } }
Stackoverflow questions related to this
In PHP, this question is one of the most high ranked questions related to json && php in stackoverflow, “Fastest way to check if a string is JSON in PHP?”. The question
Viewed 484k times. The ranking
Person asking how to do exactly this, also providing a real use case; eventhough in python, the programming language is not important. In Python
Someone has also doing exactly this , in JAVA. In Java
Open questions
Should we remove the capability of json_validate() to use the flag JSON_THROW_ON_ERROR? During the discussion in the inernals mailing list the user Rowan Tommins rowan.collins@gmail.com raised this concern.