json_decode returns null

Asked

Viewed 3,638 times

3

I have a JSON file that is at that link. I need to take and display the data in PHP, I have the following code to test:

$linkAnapro = 'http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json';

$output = file_get_contents($linkAnapro);
$json = json_decode($output);

print_r($json);

The value he returns to me is NULL, if I do print_r($output) return me the JSON. What may be happening?

3 answers

5


The url http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json is returning characters in content compatible with iso-8859-1/windows-1252, to use the json_decode it is necessary to use the utf8_encode first:

<?php
$linkAnapro = 'http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json';

$output = file_get_contents($linkAnapro);
$output = utf8_encode($output);
$json = json_decode($output);

print_r($json);

Note: This function will return false if the encoded data JSON has more than 127 elements.

Note that the json_decode returns a stdClass and that they will stay in utf-8 to convert to array use the like json_encode(..., true) and if you’re gonna use iso-8859-1 (or compatible) on your page will require a recursive function with utf8_decode not to appear those "strange" characters, follows an example of how to do:

<?php
$linkAnapro = 'http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json';

$output = file_get_contents($linkAnapro);
$output = utf8_encode($output);
$json = json_decode($output, true);

function utf8_decode_recursive(&$val, $key){
    $val = utf8_decode($val);
}

array_walk_recursive($json, 'utf8_decode_recursive');

print_r($json);
  • 1

    Thank you William, it worked!

1

The json_decode fails because the value it receives contains characters Unicode, probably GOOD (Byte Therder MArk).

One of the ways around this is to use the function utf8_encode before calling json_decode.

$linkAnapro = 'http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json';
$output = file_get_contents($linkAnapro);

$output = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($output));
$json = json_decode($output);

if (json_last_error() == 0) { // Sem erros
    print_r($json);
} else {
    echo "Erro inesperado ". json_last_error();
}

The function json_last_error() in this case returns JSON_ERROR_UTF8, if you prefer to treat this error or others that may occur, do the following:

function json_decode2($valor){
$json = json_decode($valor);

switch (json_last_error()) {
    case JSON_ERROR_NONE:
        return $json;
    case JSON_ERROR_DEPTH:
        return 'A profundidade máxima da pilha foi excedida';
    case JSON_ERROR_STATE_MISMATCH:
        return 'JSON inválido ou mal formado';
    case JSON_ERROR_CTRL_CHAR:
        return 'Erro de caractere de controle, possivelmente codificado incorretamente';
    case JSON_ERROR_SYNTAX:
        return 'Erro de sintaxe';
    case JSON_ERROR_UTF8:  // O seu caso!
        $json = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($valor));
        return json_encode($json);
    default:
        return 'Erro desconhecido';
    }   
}

To use:

$linkAnapro = 'http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json';
$output = file_get_contents($linkAnapro);

echo json_decode2($output);

Another way would be to remove the characters that are causing the problem:

$linkAnapro = 'http://s.anapro.com.br/a-p/dados/b3gkhu%252f3ohE%253d/estoque.json';

$output = file_get_contents($linkAnapro);
$json = json_decode(preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $output)); // Remove os caracteres não imprimíveis da string

if (json_last_error() == 0) { // Sem erros
    print_r($json);
} else {
    echo "Erro inesperado ". json_last_error();
}

0

In my case this method helped me json_decode(preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $output));

  • 1

    Jaime, can you explain how your answer helps solve the question?

  • @Sergio This removes control characters, which are not valid in JSON.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.