Created
June 21, 2021 09:59
-
-
Save rseon/c4702c871a32be6fb72d24b7838ba5ac to your computer and use it in GitHub Desktop.
A wrapper to safely encode UTF-8 in JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Wrapper to handle JSON errors and resolve UTF-8 errors | |
* | |
* @param mixed | |
* @param int | |
* @param int | |
* @param bool | |
* @return string|false | |
* @throw Exception | |
* | |
* @link https://stackoverflow.com/a/26760943 | |
* @link https://www.php.net/manual/en/function.json-last-error.php#refsect1-function.json-last-error-returnvalues | |
*/ | |
function safe_json_encode($value, $options = 0, $depth = 512, $utfErrorFlag = false) { | |
$encoded = json_encode($value, $options, $depth); | |
$json_error = json_last_error(); | |
switch ($json_error) { | |
// Try to resolve the UTF-8 error | |
case JSON_ERROR_UTF8: | |
$clean = utf8ize($value); | |
if ($utfErrorFlag) { | |
throw new Exception('Malformed UTF-8 characters, possibly incorrectly encoded', $json_error); | |
} | |
return safe_json_encode($clean, $options, $depth, true); | |
// No error | |
case JSON_ERROR_NONE: | |
return $encoded; | |
// Throw exceptions for all other errors | |
case JSON_ERROR_DEPTH: | |
throw new Exception('Maximum stack depth exceeded', $json_error); | |
case JSON_ERROR_STATE_MISMATCH: | |
throw new Exception('Underflow or the modes mismatch', $json_error); | |
case JSON_ERROR_CTRL_CHAR: | |
throw new Exception('Unexpected control character found', $json_error); | |
case JSON_ERROR_SYNTAX: | |
throw new Exception('Syntax error, malformed JSON', $json_error); | |
case JSON_ERROR_RECURSION: | |
throw new Exception('One or more recursive references in the value to be encoded', $json_error); | |
case JSON_ERROR_INF_OR_NAN: | |
throw new Exception('One or more NAN or INF values in the value to be encoded', $json_error); | |
case JSON_ERROR_UNSUPPORTED_TYPE: | |
throw new Exception('A value of a type that cannot be encoded was given', $json_error); | |
case JSON_ERROR_INVALID_PROPERTY_NAME: | |
throw new Exception('A property name that cannot be encoded was given', $json_error); | |
case JSON_ERROR_UTF16: | |
throw new Exception('Malformed UTF-16 characters, possibly incorrectly encoded', $json_error); | |
default: | |
throw new Exception('Unknown error', $json_error); | |
} | |
} | |
/** | |
* Encode value in UTF-8 | |
* | |
* @param array|string | |
* @return mixed | |
* | |
* @link https://stackoverflow.com/a/26760943 | |
*/ | |
function utf8ize($mixed) { | |
if (is_array($mixed)) { | |
foreach ($mixed as $key => $value) { | |
$mixed[$key] = utf8ize($value); | |
} | |
} else if (is_string ($mixed)) { | |
return utf8_encode($mixed); | |
} | |
return $mixed; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment