Php json decode обработка ошибок

(PHP 5 >= 5.2.0, PHP 7, PHP 8, PECL json >= 1.2.0)

json_decodeДекодирует строку JSON

Описание

json_decode(
    string $json,
    ?bool $associative = null,
    int $depth = 512,
    int $flags = 0
): mixed

Список параметров

json

Строка (string) json для декодирования.

Функция работает только со строками в кодировке UTF-8.

Замечание:

PHP реализует надмножество JSON, который описан в первоначальном
» RFC 7159.

associative

Если true, объекты JSON будут возвращены как
ассоциативные массивы (array); если false, объекты JSON будут возвращены как объекты (object).
Если null, объекты JSON будут возвращены как ассоциативные массивы (array) или
объекты (object) в зависимости от того, установлена ли JSON_OBJECT_AS_ARRAY
в flags.

depth

Максимальная глубина вложенности структуры, для которой будет производиться декодирование.
Значение должно быть больше 0 и меньше или равно 2147483647.

flags

Битовая маска из констант
JSON_BIGINT_AS_STRING,
JSON_INVALID_UTF8_IGNORE,
JSON_INVALID_UTF8_SUBSTITUTE,
JSON_OBJECT_AS_ARRAY,
JSON_THROW_ON_ERROR.
Поведение этих констант описаны на странице
JSON-констант.

Возвращаемые значения

Возвращает данные json, преобразованные в соответствующие
типы PHP. Значения true, false и
null возвращаются как true, false
и null соответственно. null также возвращается, если json
не может быть преобразован или закодированные данные содержат вложенных уровней
больше, чем указанный предел вложенности.

Ошибки

Начиная с PHP 8.0.0, если значение параметра depth выходит за пределы допустимого диапазона,
функция выбрасывает исключение ValueError;
ранее выдавалась ошибка уровня E_WARNING.

Список изменений

Версия Описание
7.3.0 Добавлена константа JSON_THROW_ON_ERROR
для параметра flags.
7.2.0 associative теперь nullable.
7.2.0 Добавлены константы
JSON_INVALID_UTF8_IGNORE и
JSON_INVALID_UTF8_SUBSTITUTE
для параметра flags.
7.1.0 Пустой ключ JSON («») будет преобразован в пустое свойство объекта, а не
в свойство со значением _empty_.

Примеры

Пример #1 Примеры использования json_decode()


<?php
$json
= '{"a":1,"b":2,"c":3,"d":4,"e":5}';var_dump(json_decode($json));
var_dump(json_decode($json, true));?>

Результат выполнения данного примера:

object(stdClass)#1 (5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

array(5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

Пример #2 Доступ к свойствам объектов с неправильными именами

Доступ к элементам объекта, которые содержат символы, недопустимые
в соответствии с соглашением об именах PHP (то есть дефис), может быть выполнен
путём обрамления имени элемента фигурными скобками и апострофами.


<?php

$json

= '{"foo-bar": 12345}';$obj = json_decode($json);
print
$obj->{'foo-bar'}; // 12345?>

Пример #3 Распространённая ошибка при использовании json_decode()


<?php// Следующие строки являются валидным кодом JavaScript, но не валидными JSON-данными

// Имя и значение должны помещаться в двойные кавычки
// Одинарные кавычки использовать нельзя

$bad_json = "{ 'bar': 'baz' }";
json_decode($bad_json); // null

// Имя должно обрамляться в двойные кавычки

$bad_json = '{ bar: "baz" }';
json_decode($bad_json); // null

// Не должно быть завершающей запятой (без последующего элемента)

$bad_json = '{ bar: "baz", }';
json_decode($bad_json); // null?>

Пример #4 Ошибки с глубиной вложенных объектов (depth)


<?php
// Закодируем данные с глубиной вложенности 4 (array -> array -> array -> string).
$json = json_encode(
array(
1 => array(
'English' => array(
'One',
'January'
),
'French' => array(
'Une',
'Janvier'
)
)
)
);
// Напечатаем ошибки для разных глубин.
var_dump(json_decode($json, true, 4));
echo
'Последняя ошибка: ', json_last_error_msg(), PHP_EOL, PHP_EOL;var_dump(json_decode($json, true, 3));
echo
'Последняя ошибка: ', json_last_error_msg(), PHP_EOL, PHP_EOL;
?>

Результат выполнения данного примера:

array(1) {
  [1]=>
  array(2) {
    ["English"]=>
    array(2) {
      [0]=>
      string(3) "One"
      [1]=>
      string(7) "January"
    }
    ["French"]=>
    array(2) {
      [0]=>
      string(3) "Une"
      [1]=>
      string(7) "Janvier"
    }
  }
}
Последняя ошибка: No error

NULL
Последняя ошибка: Maximum stack depth exceeded

Пример #5 json_decode() с большими целыми числами


<?php
$json
= '{"number": 12345678901234567890}';var_dump(json_decode($json));
var_dump(json_decode($json, false, 512, JSON_BIGINT_AS_STRING));?>

Результат выполнения данного примера:

object(stdClass)#1 (1) {
  ["number"]=>
  float(1.2345678901235E+19)
}
object(stdClass)#1 (1) {
  ["number"]=>
  string(20) "12345678901234567890"
}

Примечания

Замечание:

Спецификация JSON — это не JavaScript, а его подмножество.

Замечание:

В случае возникновения ошибки декодирования можно использовать
json_last_error() для определения её причины.

Lennart Hengstmengel

1 year ago


JSON can be decoded to PHP arrays by using the $associative = true option. Be wary that associative arrays in PHP can be a "list" or "object" when converted to/from JSON, depending on the keys (of absence of them).

You would expect that recoding and re-encoding will always yield the same JSON string, but take this example:

    $json = '{"0": "No", "1": "Yes"}';
    $array = json_decode($json, true);  // decode as associative hash
    print json_encode($array) . PHP_EOL;

This will output a different JSON string than the original:

    ["No","Yes"]

The object has turned into an array!

Similarly, a array that doesn't have consecutive zero based numerical indexes, will be encoded to a JSON object instead of a list.

    $array = [
        'first',
        'second',
        'third',
    ];
    print json_encode($array) . PHP_EOL;
    // remove the second element
    unset($array[1]);
    print json_encode($array) . PHP_EOL;

The output will be:

    ["first","second","third"]
    {"0":"first","2":"third"}

The array has turned into an object!

In other words, decoding/encoding to/from PHP arrays is not always symmetrical, or might not always return what you expect!

On the other hand, decoding/encoding from/to stdClass objects (the default) is always symmetrical.

Arrays may be somewhat easier to work with/transform than objects. But especially if you need to decode, and re-encode json, it might be prudent to decode to objects and not arrays.

If you want to enforce an array to encode to a JSON list (all array keys will be discarded), use:

    json_encode(array_values($array));

If you want to enforce an array to encode to a JSON object, use:

    json_encode((object)$array);

See also: https://www.php.net/manual/en/function.array-is-list.php


greaties at ghvernuft dot nl

3 months ago


To load an object with data in json format:
(bugfixed my previous comment)

<?php
function loadJSON($Obj, $json)
{
   
$dcod = json_decode($json);
   
$prop = get_object_vars ( $dcod );
    foreach(
$prop as $key => $lock)
    {
        if(
property_exists ( $Obj $key ))
        {
            if(
is_object($dcod->$key))
            {
               
loadJSON($Obj->$key, json_encode($dcod->$key));
            }
            else
            {
               
$Obj->$key = $dcod->$key;
            }
        }
    }
    return
$Obj;
}
?>

Tested with:

<?php
class Name
{
  public
$first;
  public
$last;
  public function
fullname()
  {
    return
$this->first . " " . $this->last;
  }
}
$json = '{"first":"John","last":"Smith"}';$infull = loadJSON((new Name), $json);
echo
$infull->fullname();


Alien426

2 years ago


Browsers don't choke on integers _starting_ with BigInt (64 bits), but before that (53 bits). The introduction of BigInt to modern browsers doesn't help much, when JSON handling functions do not support it. So I am trying to remedy that. My approach is to handle the decoded array before re-encoding it to a string:
<?php
function fix_large_int(&$value)
{
  if (
is_int($value) && $value > 9007199254740991)
   
$value = strval($value);
}
$json_str = '{"id":[1234567890123456789,12345678901234567890]}';
$json_arr = json_decode($json_str, flags: JSON_BIGINT_AS_STRING | JSON_OBJECT_AS_ARRAY);
echo(
json_encode($json_arr)); // {"id":[1234567890123456789,"12345678901234567890"]} (BigInt is already converted to a string here)
array_walk_recursive($json_arr, 'fix_large_int');
echo(
json_encode($json_arr)); // {"id":["1234567890123456789","12345678901234567890"]}
?>

cubefox at web dot NOSPAMPLEASE dot de

2 years ago


Warning: As the section "return values" mentions, the return value NULL is ambiguos. To repeat, it can mean three things:

* The input string had the value "null"
* There was an error while parsing the input data
* The encoded data was deeper than the recursion limit

To distinguish these cases, json_last_error() can be used.


greaties at ghvernuft dot nl

2 years ago


To load an object with data in json format:

function loadJSON($Obj, $json)
{
    $dcod = json_decode($json);
    $prop = get_object_vars ( $dcod );
    foreach($prop as $key => $lock)
    {
        if(property_exists ( $Obj ,  $key ))
        {
            if(is_object($dcod->$key))
            {
                loadJSON($Obj->$key, json_encode($dcod->$key));
            }
            else
            {
                $Obj->$key = $dcod->$key;
            }
        }
    }
}


as-works at narod dot ru

1 year ago


On some PHP7+ systems php_json functions can be undefined (i faced it on Oracle Linux Enterprice with php 7.4 installed from REMI repository). If you have the same problem, try to install separated php-json module:

# yum install php-json

Hope this helps.


Anonymous

1 year ago


<?php

$array

= [0 => "foo", 1 => "bar", 2 => ["baz"]];$associative = false;var_dump(
   
json_decode(
       
json_encode($array),
       
$associative
   
)
);
?>

The above will output
<?php
/*
array (size=3)
  0 => string 'foo' (length=3)
  1 => string 'bar' (length=3)
  2 =>
    array (size=1)
      0 => string 'baz' (length=3)
*/
?>

Considering <?php $associative = false; ?> one might expect
<?php
/*
object(stdClass)
  public '0' => string 'foo' (length=3)
  public '1' => string 'bar' (length=3)
  public '2' =>
    object(stdClass)
      public '0' => string 'baz' (length=3)
*/
?>

an stdClass object instead of an array, but this is incorrect.
json_decode will always return an array for a sequentially encoded array, regardless of the ?bool $associative 2nd argument

Which is inline with the above mentioned docs/spec
    > Returns the value encoded in json in appropriate PHP type

Considering that the 1st arg was a sequentially encoded array as a json string
    '["foo","bar",["baz"]]'


mattia

2 years ago


if you're using ajax to post, and your JavaScript code looks like this:

<code>
    var xhttp = new XMLHttpRequest();
    xhttp.open("POST", "something.php", true);
    xhttp.setRequestHeader("Content-Type", "application/json");
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
             // do something
        }
    };
    var data = {some: "thing"};
    xhttp.send(JSON.stringify(data));
</code>

then in <code>something.php</code> you can retrieve your json by doing

<?php
$data
= json_decode(file_get_contents("php://input"), true);
?>


I just spent an hour going through all the possible solutions on this page. I took the liberty of collective all these possible solutions into one function, to make it quicker and easier to try and debug.

I hope it can be of use to someone else.

<?php
/**
 * Decontaminate text
 *
 * Primary sources:
 *  - https://stackoverflow.com/questions/17219916/json-decode-returns-json-error-syntax-but-online-formatter-says-the-json-is-ok
 *  - https://stackoverflow.com/questions/2348152/detect-bad-json-data-in-php-json-decode
 */
function decontaminate_text(
  $text,
  $remove_tags = true,
  $remove_line_breaks = true,
  $remove_BOM = true,
  $ensure_utf8_encoding = true,
  $ensure_quotes_are_properly_displayed = true,
  $decode_html_entities = true
){

  if ( '' != $text && is_string( $text ) ) {
    $text = preg_replace( '@<(script|style)[^>]*?>.*?</\1>@si', '', $text );
    $text = str_replace(']]>', ']]&gt;', $text);

    if( $remove_tags ){
      // Which tags to allow (none!)
      // $text = strip_tags($text, '<p>,<strong>,<span>,<a>');
      $text = strip_tags($text, '');
    }

    if( $remove_line_breaks ){
      $text = preg_replace('/[rnt ]+/', ' ', $text);
      $text = trim( $text );
    }

    if( $remove_BOM ){
      // Source: https://stackoverflow.com/a/31594983/1766219
      if( 0 === strpos( bin2hex( $text ), 'efbbbf' ) ){
        $text = substr( $text, 3 );
      }
    }

    if( $ensure_utf8_encoding ){

      // Check if UTF8-encoding
      if( utf8_encode( utf8_decode( $text ) ) != $text ){
        $text = mb_convert_encoding( $text, 'utf-8', 'utf-8' );
      }
    }

    if( $ensure_quotes_are_properly_displayed ){
      $text = str_replace('&quot;', '"', $text);
    }

    if( $decode_html_entities ){
      $text = html_entity_decode( $text );
    }

    /**
     * Other things to try
     * - the chr-function: https://stackoverflow.com/a/20845642/1766219
     * - stripslashes (THIS ONE BROKE MY JSON DECODING, AFTER IT STARTED WORKING, THOUGH): https://stackoverflow.com/a/28540745/1766219
     * - This (improved?) JSON-decoder didn't help me, but it sure looks fancy: https://stackoverflow.com/a/43694325/1766219
     */

  }
  return $text;
}

// Example use
$text = decontaminate_text( $text );

// $text = decontaminate_text( $text, false ); // Debug attempt 1
// $text = decontaminate_text( $text, false, false ); // Debug attempt 2
// $text = decontaminate_text( $text, false, false, false ); // Debug attempt 3

$decoded_text = json_decode( $text, true );
echo json_last_error_msg() . ' - ' . json_last_error();
?>

I’ll maintain it here: https://github.com/zethodderskov/decontaminate-text-in-php/blob/master/decontaminate-text-preparing-it-for-json-decode.php

json_decode

(PHP 5 >= 5.2.0, PECL json >= 1.2.0, PHP 7)

json_decodeДекодирует JSON строку

Описание

mixed json_decode
( string $json
[, bool $assoc = false
[, int $depth = 512
[, int $options = 0
]]] )

Список параметров

json

json строка (string) для декодирования.

Эта функция работает только со строками в UTF-8 кодировке.

Замечание:

PHP реализует надмножество JSON, который описан в первоначальном
» RFC 4627, — также кодируя и декодируя скалярные типы и NULL.
RFC 4627 поддерживает эти значения только в случае,
если они находятся внутри массива или объекта.

И хотя это надмножество согласуется с расширенным определением
«JSON текста» из новых » RFC 7159
(который старается заменить собой RFC 4627) и » ECMA-404,
это все равно может приводить к проблемам совместимости со старыми парсерами JSON, которые
строго придерживаются RFC 4627 с кодированием скалярных значений.

assoc

Если TRUE, возвращаемые объекты будут преобразованы в ассоциативные массивы.

depth

Указывает глубину рекурсии.

options

Битовая маска опций декодирования JSON. В настоящий момент поддерживается только
JSON_BIGINT_AS_STRING
(по умолчанию большие целые числа приводятся к числам с плавающей запятой (float))

Возвращаемые значения

Возвращает данные json преобразованные в соответствующие
типы PHP. Значения true, false и
null возвращаются как TRUE, FALSE
и NULL соответственно. NULL также возвращается, если json
не может быть преобразован или закодированные данные содержат вложенных уровней
больше, чем допустимый предел для рекурсий.

Примеры

Пример #1 Пример использования json_decode()


<?php
$json 
'{"a":1,"b":2,"c":3,"d":4,"e":5}';var_dump(json_decode($json));
var_dump(json_decode($jsontrue));?>

Результат выполнения данного примера:

object(stdClass)#1 (5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

array(5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

Пример #2 Доступ к свойствам объектов с неправильными именами

Доступ к элементам объекта, которые содержат символы недопустимые
согласно соглашению об именах PHP (т.е. дефис), может производиться
путем обрамления имени элемента фигурными скобками и апострофами.


<?php

$json 

'{"foo-bar": 12345}';$obj json_decode($json);
print 
$obj->{'foo-bar'}; // 12345?>

Пример #3 Распространенная ошибка при использовании json_decode()


<?php// Следующие строки являются валидным кодом JavaScript, но не валидными JSON данными

// Имя и значение должны помещаться в двойные кавычки
// Одинарные кавычки использовать нельзя 

$bad_json "{ 'bar': 'baz' }";
json_decode($bad_json); // null

// Имя должно обрамляться в двойные кавычки

$bad_json '{ bar: "baz" }';
json_decode($bad_json); // null

// Не должно быть завершающей запятой (без последующего элемента)

$bad_json '{ bar: "baz", }';
json_decode($bad_json); // null?>

Пример #4 Ошибки с глубиной вложенных объектов (depth)


<?php
// Кодирование данных.
$json json_encode(
    array(
        
=> array(
            
'English' => array(
                
'One',
                
'January'
            
),
            
'French' => array(
                
'Une',
                
'Janvier'
            
)
        )
    )
);
// Создаем массив с ошибками.
$constants get_defined_constants(true);
$json_errors = array();
foreach (
$constants["json"] as $name => $value) {
    if (!
strncmp($name"JSON_ERROR_"11)) {
        
$json_errors[$value] = $name;
    }
}
// Отображаем ошибки для разных глубин рекурсий
foreach (range(43, -1) as $depth) {
    
var_dump(json_decode($jsontrue$depth));
    echo 
'Last error: '$json_errors[json_last_error()], PHP_EOLPHP_EOL;
}
?>

Результат выполнения данного примера:

array(1) {
  [1]=>
  array(2) {
    ["English"]=>
    array(2) {
      [0]=>
      string(3) "One"
      [1]=>
      string(7) "January"
    }
    ["French"]=>
    array(2) {
      [0]=>
      string(3) "Une"
      [1]=>
      string(7) "Janvier"
    }
  }
}
Last error: JSON_ERROR_NONE

NULL
Last error: JSON_ERROR_DEPTH

Пример #5 json_decode() с большими целыми числами


<?php
$json 
'{"number": 12345678901234567890}';var_dump(json_decode($json));
var_dump(json_decode($jsonfalse512JSON_BIGINT_AS_STRING));?>

Результат выполнения данного примера:

object(stdClass)#1 (1) {
  ["number"]=>
  float(1.2345678901235E+19)
}
object(stdClass)#1 (1) {
  ["number"]=>
  string(20) "12345678901234567890"
}

Примечания

Замечание:

Спецификация JSON не тоже самое, что и JavaScript, но является его частью.

Замечание:

В случае ошибки декодирования можно использовать
json_last_error() для определения ее причины.

Список изменений

Версия Описание
5.6.0 Недопустимые варианты true,
false и null не в нижнем регистре больше
не допускаются во входящих данных, и приводят к предупреждениям.
5.4.0 Был добавлен параметр options.
5.3.0 Добавлен опциональный параметр depth.
Глубина рекурсии по умолчанию увеличено с 128 до 512
5.2.3 Глубина рекурсии увеличена с 20 до 128
5.2.1 Добавлена поддержка декодирования основных типов JSON.

Вернуться к: JSON Функции

One of the new features coming to PHP 7.3 is better error handling for json_encode() and json_decode(). The RFC was unanimously accepted by a 23 to 0 vote. Let’s take a look at how we handle JSON errors in <= PHP 7.2, and the new improvements coming in PHP 7.3.

Background

In the current stable, PHP v7.2, if you want to determine if JSON is invalid, you have to use the json_last_error() function to verify:

>>> json_decode("{");

=> null

>>> json_last_error();

=> 4

>>> json_last_error() === JSON_ERROR_NONE

=> false

>>> json_last_error_msg()

=> "Syntax error"

For example, in the Laravel IlluminateEncryptionEncrypter class here’s a check to make sure calling json_encode() doesn’t result in an error:

// Once we get the encrypted value we'll go ahead and base64_encode the input

// vector and create the MAC for the encrypted value so we can then verify

// its authenticity. Then, we'll JSON the data into the "payload" array.

$json = json_encode(compact('iv', 'value', 'mac'));

if (json_last_error() !== JSON_ERROR_NONE) {

throw new EncryptException('Could not encrypt the data.');

}

return base64_encode($json);

We can at least determine if JSON encoding/decoding had an error, but it’s a little clunky compared to throwing an exception, which packages the error code and message neatly together.

Although you have to opt-in, v7.3 has an excellent way of allowing you to catch and handle JSON exceptions—let’s check out the new flag we can use!

The Throw on Error Flag in PHP 7.3

With the new option flag JSON_THROW_ON_ERROR it’s possible to rewrite this block of code with a try/catch. Maybe some something like the following:

use JsonException;

try {

$json = json_encode(compact('iv', 'value', 'mac'), JSON_THROW_ON_ERROR);

return base64_encode($json);

} catch (JsonException $e) {

throw new EncryptException('Could not encrypt the data.', 0, $e);

}

I think this new style is especially useful for userland code when you receive some JSON data and instead of digging around for json_last_error() and the matching flag, your JSON encoding and decoding can take advantage of the error handler.

The json_decode() function has a few more arguments, and will look something like the following in PHP 7.3 if you want to take advantage of error handling:

use JsonException;

try {

return json_decode($jsonString, $assoc = true, $depth = 512, JSON_THROW_ON_ERROR);

} catch (JsonException $e) {

// Handle the JSON Exception

}

// Or even just let it bubble up...

/**

* Decode a JSON string into an array

*

* @return array

* @throws JsonException

*/

function decode($jsonString) {

return json_decode($jsonString, $assoc = true, $depth = 512, JSON_THROW_ON_ERROR);

}

Getting the Error Code and Message

Previously you retrieve the JSON error code and message using the following functions:

// Error code

json_last_error();

// Human-friendly message

json_last_error_msg();

If you use the new JSON_THROW_ON_ERROR flag, here’s how you’ll get the code and message:

try {

return json_decode($jsonString, $assoc = true, $depth = 512, JSON_THROW_ON_ERROR);

} catch (JsonException $e) {

$e->getMessage(); // like json_last_error_msg()

$e->getCode(); // like json_last_error()

}

See the base Exception class for more API details, the JsonException exception is a subclass of Exception.

JSON’s Default Behavior in PHP 7.3

When upgrading to PHP 7.3, your code will be backward compatible on day one and continue to work as expected.

PHP’s default json_encode|decode() behavior hasn’t changed, the throw on error RFC adds a new option and exception class.

Learn More

You can learn all about the most prominent features coming to PHP 7.3 in our post announcing the PHP 7.3 Alpha 1 release last week. Also, read through the RFC for JSON_THROW_ON_ERROR for full details on the proposal coming to PHP 7.3.

Unfortunately, the error handling in the earlier versions of PHP is non-existent. It wasn’t until PHP version 5.3.0 that the function json_last_error was introduced that. Before that, json_encode would return a NULL value or a FALSE value and you’d have to use an external JSON validation tool to try and figure out what was going wrong.

For example, if your data had special (non-UTF8) characters, the json_encode function would often return a NULL value. If the depth of your PHP array was too “deep”, then it would return a FALSE value. The json_decode function was also pretty similar in the way that it returned NULL whenever it received malformed / incorrect JSON strings.

Prior to PHP 5.3.0, JSON error handling in PHP looked a little like this (throwing Exceptions):

$val = json_encode($myArr);
if($val === false || is_null($val)){
    throw new Exception('Could not encode JSON');
}

or, with json_decode:

$val = json_decode($structure, true);
if(!is_array($val)){
    throw new Exception('Could not decode JSON');
}

Thankfully, in PHP 5.3.0, the function json_last_error was introduced. If an error has occurred, it will return one of the following constants:

  • JSON_ERROR_NONE: No error has occured.
  • JSON_ERROR_DEPTH: Max depth exceeded.
  • JSON_ERROR_STATE_MISMATCH: Invalid JSON.
  • JSON_ERROR_CTRL_CHAR: Bad character was found.

In PHP 5.3.3, another constant was added:

  • JSON_ERROR_UTF8: Bad UTF8 character was found. Incorrect encoding.

Then, in PHP 5.5, they added three more constants:

  • JSON_ERROR_RECURSION: Recursion detected.
  • JSON_ERROR_INF_OR_NAN: One or more NAN or INF values in the value to be encoded.
  • JSON_ERROR_UNSUPPORTED_TYPE: An unsupported type was found.

Using these constants, we can carry out our error handling like so:

<?php

//Attempt to decode JSON.
$decoded = json_decode($arr);

//Backwards compatability.
if(!function_exists('json_last_error')){
    if($decoded === false || $decoded === null){
        throw new Exception('Could not decode JSON!');
    }
} else{
    
    //Get the last JSON error.
    $jsonError = json_last_error();
    
    //In some cases, this will happen.
    if(is_null($decoded) && $jsonError == JSON_ERROR_NONE){
        throw new Exception('Could not decode JSON!');
    }
    
    //If an error exists.
    if($jsonError != JSON_ERROR_NONE){
        $error = 'Could not decode JSON! ';
        
        //Use a switch statement to figure out the exact error.
        switch($jsonError){
            case JSON_ERROR_DEPTH:
                $error .= 'Maximum depth exceeded!';
            break;
            case JSON_ERROR_STATE_MISMATCH:
                $error .= 'Underflow or the modes mismatch!';
            break;
            case JSON_ERROR_CTRL_CHAR:
                $error .= 'Unexpected control character found';
            break;
            case JSON_ERROR_SYNTAX:
                $error .= 'Malformed JSON';
            break;
            case JSON_ERROR_UTF8:
                 $error .= 'Malformed UTF-8 characters found!';
            break;
            default:
                $error .= 'Unknown error!';
            break;
        }
        throw new Exception($error);
    }
}

Unfortunately, this isn’t the type of code that you should be repeating throughout your script. If you stay true to the DRY (Don’t Repeat Yourself) principle (which you should), then you will wrap this kind of error checking into a function or a class method.

Personally, I would prefer it if json_last_error returned a string-based error message (like the internal XML library does). That way, you wouldn’t need to implement an ugly-looking switch statement.

Still, at least it is far more informative than it used to be!

Понравилась статья? Поделить с друзьями:
  • Php ini вывод ошибок в браузер
  • Php ini включить показ ошибок
  • Php ini включить вывод ошибок
  • Php ini включить все ошибки
  • Php file get contents ошибки