Skip to content

Instantly share code, notes, and snippets.

@rseon
Created June 21, 2021 09:59
Show Gist options
  • Save rseon/c4702c871a32be6fb72d24b7838ba5ac to your computer and use it in GitHub Desktop.
Save rseon/c4702c871a32be6fb72d24b7838ba5ac to your computer and use it in GitHub Desktop.
A wrapper to safely encode UTF-8 in JSON
<?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