rfc:is_json

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:is_json [2022/08/15 19:12] juan_moralesrfc:is_json [2022/08/17 14:04] (current) juan_morales
Line 5: Line 5:
   * Status: Draft   * Status: Draft
   * First Published at: http://wiki.php.net/rfc/is_json   * First Published at: http://wiki.php.net/rfc/is_json
 +  * Implementation: https://github.com/php/php-src/pull/9355
  
 ===== Preliminary note ===== ===== Preliminary note =====
Line 14: Line 15:
  
 Most userland implementations to achieve this are done using json_decode() which by design generates an object/array while parsing the string, ergo using memory and processing, that could be save. Most userland implementations to achieve this are done using json_decode() which by design generates an object/array while parsing the string, ergo using memory and processing, that could be save.
- 
-===== Fundaments/Reasons ===== 
-==== Disadvantages of using json_decode ==== 
- 
-By design, json_decode() generates an object/array 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. 
- 
-==== Disadvantages of using regex ==== 
- 
-Using a regex for this task forces different, error-prone, hard to maintain, implementations. 
- 
-==== Needs from major projects and developers ==== 
- 
-In the "References" section, there is a list of major open-source php projects needing this feature; also in th mntioned section can find a link to one of the most popular StackOverflow questions, which somehow reflects the need from our developers to have a feature like this included. 
- 
-==== Why not using a 3rd party package for this ==== 
- 
-- This feature is very web related, which is a huge coincidence with the first lines of the default RFC template provided to "us": 
-<blockquote> 
-PHP is and should remain: 
-> 1) a pragmatic web-focused language .... 
-</blockquote> 
- 
-- We should not force the community to install 3rd party packages for this kind of features (feature totally aligned with PHP's principles, and very easy to achieve), which would generate a dependency between the project and the package. 
- 
-==== 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 in memory for it. 
- 
-==== Name of the function ==== 
- 
-If the links provided in the "References" section are checked, one can see that some of those major projects have created a function called this isJson(). 
  
 ===== Proposal ===== ===== Proposal =====
Line 76: Line 46:
  
 Returns **true** if the string passed contains a valid json, otherwise returns **false**. Returns **true** if the string passed contains a valid json, otherwise returns **false**.
 +
 +==== Extra behavior ====
 +-
 +==== Examples ====
 +-
 +===== Fundaments/Reasons =====
 +==== Disadvantages of using json_decode ====
 +
 +By design, json_decode() generates an object/array 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.
 +
 +==== Disadvantages of using regex ====
 +
 +Using a regex for this task forces different, error-prone, hard to maintain, implementations.
 +
 +==== Needs from major projects and developers ====
 +
 +In the "References" section, there is a list of major open-source php projects needing this feature; also in th mntioned section can find a link to one of the most popular StackOverflow questions, which somehow reflects the need from our developers to have a feature like this included.
 +
 +==== 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 in memory for it.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 101: Line 92:
  
 ===== References ===== ===== References =====
-- (To be done later+ 
--- Links to external referencesdiscussions or RFCs +==== Major Open-Source projects that will benefit out of this ==== 
--- Links to major open-source projects emulating this function using json_decode + 
--- Link to Stackoverflow pointing the question, which this proposed function satisfy the needs+[[https://github.com/symfony/symfony/blob/870eeb975feb1abb4b8a1722e1fd57beeab2b230/src/Symfony/Component/Validator/Constraints/JsonValidator.php|Symfony Framework]] 
 + 
 +<code php> 
 +class JsonValidator extends ConstraintValidator 
 +</code> 
 + 
 +[[https://github.com/laravel/framework/blob/302a579f00ebcb2573f481054cbeadad9c970605/src/Illuminate/Validation/Concerns/ValidatesAttributes.php|Laravel Framework]] 
 + 
 +<code php> 
 +    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; 
 +    } 
 +</code> 
 + 
 +[[https://github.com/laravel/framework/blob/61eac9cae4717699ecb3941b16c3d775820d4ca2/src/Illuminate/Support/Str.php|Laravel Framework]] 
 + 
 +<code php> 
 +    public static function isJson($value) 
 +    { 
 +</code> 
 + 
 +[[https://github.com/magento/magento2/blob/7c6b6365a3c099509d6f6e6c306cb1821910aab0/app/code/Magento/User/Block/Role/Grid/User.php|Magento]] 
 + 
 +<code php> 
 +    private function getJSONString($input) 
 +    { 
 +        $output = json_decode($input); 
 +        return $output ? $this->_jsonEncoder->encode($output) : '{}'; 
 +    } 
 +</code> 
 + 
 +[[https://github.com/magento/magento2/blob/7c6b6365a3c099509d6f6e6c306cb1821910aab0/lib/internal/Magento/Framework/DB/DataConverter/SerializedToJson.php|Magento]] 
 + 
 +<code php> 
 +    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; 
 +    } 
 +</code> 
 + 
 +[[https://github.com/magento/magento2/blob/7c6b6365a3c099509d6f6e6c306cb1821910aab0/lib/internal/Magento/Framework/Serialize/JsonValidator.php|Magento]] 
 + 
 +<code php> 
 +    public function isValid($string) 
 +    { 
 +        if ($string !== false && $string !== null && $string !== '') { 
 +            json_decode($string); 
 +            if (json_last_error() === JSON_ERROR_NONE) { 
 +                return true; 
 +            } 
 +        } 
 +        return false; 
 +    } 
 +</code> 
 + 
 + 
 +[[https://github.com/getgrav/grav/blob/3e7f67f589267e61f823d19824f3ee1b9a8a38ff/system/src/Grav/Common/Data/Validation.php|getgrav]] 
 + 
 +<code php> 
 +    public static function validateJson($value, $params) 
 +    { 
 +        return (bool) (@json_decode($value)); 
 +    } 
 +</code> 
 + 
 + 
 +[[https://github.com/symfony/http-kernel/blob/94986633e4c3e7facb7defbd094a2e1170486ab5/DataCollector/RequestDataCollector.php|Symfony htp-kernel ]] 
 + 
 +<code php> 
 +    public function getPrettyJson() 
 +    { 
 +        $decoded = json_decode($this->getContent()); //<------ here  
 + 
 +        return \JSON_ERROR_NONE === json_last_error() ? json_encode($decoded, \JSON_PRETTY_PRINT) : null; 
 +    } 
 +</code> 
 + 
 + 
 +[[https://github.com/Respect/Validation/blob/3dcd859d986f1b586b5539ea19962723ab7352ed/library/Rules/Json.php|Respect / Validation]] 
 + 
 +<code php> 
 +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; 
 +    } 
 +
 +</code> 
 + 
 +[[https://github.com/Respect/Validation/blob/3dcd859d986f1b586b5539ea19962723ab7352ed/library/Rules/Json.php|Respect / Validation]] 
 + 
 +<code php> 
 +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; 
 +    } 
 +
 +</code> 
 + 
 +[[https://github.com/humhub/humhub/blob/26d7e2667a9317057abe335a056ac8e8f4d675fb/protected/humhub/modules/web/security/controllers/ReportController.php|humhub]] 
 + 
 + 
 +<code php> 
 +    public function actionIndex() 
 +    { 
 +        Yii::$app->response->statusCode = 204; 
 + 
 +        if(!SecuritySettings::isReportingEnabled()) { 
 +            return; 
 +        } 
 + 
 +        $json_data = file_get_contents('php://input'); 
 +        if ($json_data = json_decode($json_data)) { //<----- json_decode() just to check if is valid json-string only 
 +            $json_data = json_encode($json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); 
 +            $json_data = preg_replace('/\'nonce-[^\']*\'/', "'nonce-xxxxxxxxxxxxxxxxxxxxxxxx'", $json_data); 
 +            Yii::error($json_data, 'web.security'); 
 +        } 
 +    } 
 +</code> 
 + 
 +[[https://github.com/PrestaShop/PrestaShop/blob/24f9e510ecb0cb002ac3f4834f3210e8d9359899/classes/Validate.php|Prestashop]] 
 + 
 +<code php> 
 +    public static function isJson($string) 
 +    { 
 +        json_decode($string); 
 + 
 +        return json_last_error() == JSON_ERROR_NONE; 
 +    } 
 +</code> 
 + 
 +[[https://github.com/wp-cli/wp-cli/blob/f3e4b0785aa3d3132ee73be30aedca8838a8fa06/php/utils.php|Wordpress CLI]] 
 + 
 +<code php> 
 +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; 
 +
 +</code> 
 + 
 +[[https://github.com/joomla/joomla-cms/blob/09d14c65f25f9bc76f2698e69c4d7b35f43bc848/libraries/src/Form/Field/AccessiblemediaField.php|JOOMLA CMS]] 
 + 
 +<code php> 
 +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 = ''; 
 +        } 
 +    } 
 + 
 +</code> 
 + 
 + 
 + 
 +==== 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?". [[https://stackoverflow.com/questions/6041741/fastest-way-to-check-if-a-string-is-json-in-php|The question]] 
 + 
 +Viewed 484k times. [[https://stackoverflow.com/questions/tagged/php%20json?sort=MostVotes&edited=true|The ranking]] 
 + 
 +Person asking how to do exactly this, also providing a real use case; eventhough in python, the programming language is not important. [[https://stackoverflow.com/questions/5508509/how-do-i-check-if-a-string-is-valid-json-in-python|In Python]] 
 + 
 +Someone has also doing exactly this , in JAVA. [[https://stackoverflow.com/questions/3679479/check-if-file-is-json-java|In Java]]
  
 ===== Rejected Features ===== ===== Rejected Features =====
 - No rejected features currently. - No rejected features currently.
rfc/is_json.1660590721.txt.gz · Last modified: 2022/08/15 19:12 by juan_morales