PHP Debugging JSON errors


Example

When json_encode or json_decode fails to parse the string provided, it will return false. PHP itself will not raise any errors or warnings when this happens, the onus is on the user to use the json_last_error() and json_last_error_msg() functions to check if an error occurred and act accordingly in your application (debug it, show an error message, etc.).

The following example shows a common error when working with JSON, a failure to decode/encode a JSON string (due to the passing of a bad UTF-8 encoded string, for example).

// An incorrectly formed JSON string
$jsonString = json_encode("{'Bad JSON':\xB1\x31}");

if (json_last_error() != JSON_ERROR_NONE) {
    printf("JSON Error: %s", json_last_error_msg());
}

#> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded

json_last_error_msg

json_last_error_msg() returns a human readable message of the last error that occurred when trying to encode/decode a string.

  • This function will always return a string, even if no error occurred.
    The default non-error string is No Error
  • It will return false if some other (unknown) error occurred
  • Careful when using this in loops, as json_last_error_msg will be overridden on each iteration.

You should only use this function to get the message for display, not to test against in control statements.

// Don't do this:
if (json_last_error_msg()){} // always true (it's a string)
if (json_last_error_msg() != "No Error"){} // Bad practice

// Do this: (test the integer against one of the pre-defined constants)
if (json_last_error() != JSON_ERROR_NONE) {
    // Use json_last_error_msg to display the message only, (not test against it)
    printf("JSON Error: %s", json_last_error_msg());
}

This function doesn't exist before PHP 5.5. Here is a polyfill implementation:

if (!function_exists('json_last_error_msg')) {
    function json_last_error_msg() {
        static $ERRORS = array(
            JSON_ERROR_NONE => 'No error',
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
            JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
            JSON_ERROR_SYNTAX => 'Syntax error',
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
        );

        $error = json_last_error();
        return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
    }
}

json_last_error

json_last_error() returns an integer mapped to one of the pre-defined constants provided by PHP.

ConstantMeaning
JSON_ERROR_NONENo error has occurred
JSON_ERROR_DEPTHThe maximum stack depth has been exceeded
JSON_ERROR_STATE_MISMATCHInvalid or malformed JSON
JSON_ERROR_CTRL_CHARControl character error, possibly incorrectly encoded
JSON_ERROR_SYNTAXSyntax error (since PHP 5.3.3)
JSON_ERROR_UTF8Malformed UTF-8 characters, possibly incorrectly encoded (since PHP 5.5.0)
JSON_ERROR_RECURSIONOne or more recursive references in the value to be encoded
JSON_ERROR_INF_OR_NANOne or more NAN or INF values in the value to be encoded
JSON_ERROR_UNSUPPORTED_TYPEA value of a type that cannot be encoded was given