简体   繁体   中英

json_decode - returning NULL

The below JSON string is being passed into json_decode() , and it is returning NULL .

{"total_goals":26,"total_games":17,"average_goals":"1.53"}

Here's my code:

$homeJSON = file_get_contents("http://strategy-bets.com/archive/archive.php?baseurl=http://www.totalcorner.com".$Home_Team_Link);

$homeJSON = str_replace("\xEF\xBB\xBF",'',$homeJSON); 
$homeJSON = rtrim($homeJSON);
$homeJSON = html_entity_decode($homeJSON);
$homeJSON = preg_replace('/\s+/', '', $homeJSON);
$clean = rtrim($homeJSON, "\x00..\x1F");

$home_decoded = json_decode($clean);

$home_decoded is still NULL .

First of all, json_decode() is returning NULL due to an error condition. You can determine the nature of the error condition using json_last_error() , which returns an integer constant representing the type of error. You can decode these using this function (built from the error codes described on the json_last_error() manual page):

<?php
function decodeJsonError($errorCode)
{
    $errors = array(
        JSON_ERROR_NONE => 'No error has occurred',
        JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
        JSON_ERROR_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',
        JSON_ERROR_RECURSION => 'One or more recursive references in the value to be encoded',
        JSON_ERROR_INF_OR_NAN => 'One or more NAN or INF values in the value to be encoded',
        JSON_ERROR_UNSUPPORTED_TYPE => 'A value of a type that cannot be encoded was given'
    );

    if (isset($errors[$errorCode]))
    {
        return $errors[$errorCode];
    }

    return 'Unknown error';
}

Now, I can't figure out exactly what the API you're calling is returned, because a valid link wasn't provided (and I understand this may be sensitive data), but, let's try a different approach, and just try to extract only the JSON from whatever the API is returning:

<?php

$homeJSON = file_get_contents("http://strategy-bets.com/archive/archive.php?baseurl=http://www.totalcorner.com".$Home_Team_Link);

if (!preg_match('/(\{"[^\}]+\})/', $homeJSON, $matches))
{
    echo "An error occurred; no JSON found.";
    return;
}

$home_decoded = json_decode($matches[1]);

This is working against the actual output from the API (without a proper URL) for me:

file_get_contents("http://strategy-bets.com/archive/archive.php?baseurl=http://www.totalcorner.com");

Even though the API itself is returning HTML mixed in with the JSON.

Edit : Since you provided a valid URL, I did some more debugging:

php > print_r(array_map('dechex', array_map('ord', str_split($homeJSON))));
Array
(
    [0] => ef
    [1] => bb
    [2] => bf
    [3] => 7b
    [4] => 22
    [5] => 74
    [6] => 6f
    [7] => 74
    [8] => 61
    [9] => 6c
    ...

Byte 7b is the opening { where the valid JSON starts. Bytes 0-3 are a UTF-8 Byte Order Mark . So, while my regex solution above will still work, we can also just clean up the BOM and any stray null characters like this:

$homeJSON = file_get_contents("http://strategy-bets.com/archive/archive.php?baseurl=http://www.totalcorner.com".$Home_Team_Link);

$homeJSON = trim($homeJSON, "\x0\xEF\xBB\xBF");

$home_decoded = json_decode($homeJSON);

This gives me:

php > var_dump(json_decode($jsonCopy));
object(stdClass)#1 (3) {
  ["total_goals"]=>
  int(26)
  ["total_games"]=>
  int(17)
  ["average_goals"]=>
  string(4) "1.53"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM