PHP json_decode () devuelve NULL con JSON aparentemente válido?

6 minutos de lectura

Avatar de usuario de Joel A. Villarreal Bertoldi
Joel A. Villarreal Bertoldi

Tengo este objeto JSON almacenado en un archivo de texto sin formato:

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

Cuando trato de decodificarlo con json_decode(), devuelve NULL. ¿Por qué? El archivo es legible (intenté hacer eco file_get_contents() y funcionó bien).

He probado JSON contra http://jsonlint.com/ y es perfectamente válido.

¿Qué pasa aquí?

  • Trabajando con PHP 5.2.9; por lo tanto, no puedo usar json_last_error().

    – Joel A. Villarreal Bertoldi

    9 de marzo de 2010 a las 15:57

  • También tenga en cuenta que esto puede ocurrir con otros caracteres no válidos en medio del archivo. Acabo de hacer que json_decode() devuelva nulo porque la cadena contenía uno de esos guiones especiales, probablemente pegado desde MS Word, y luego quizás mal codificado. Para identificar posibles caracteres problemáticos, abra el archivo JSON (que usé en Notepad ++), cambie la codificación (sin convertir) y guárdelo como una copia. Luego diferencie los dos archivos (utilicé WinMerge).

    – LinusR

    17 de enero de 2012 a las 17:15


  • (Problema del Bloc de notas de Windows) Por favor, consulte esto, también compartí el problema y lo arreglé: stackoverflow.com/questions/10290849/…

    – Félix Aballí

    19 de septiembre de 2014 a las 14:49

  • posible duplicado de json_decode devuelve NULL después de la llamada al servicio web

    – usuario

    3 de diciembre de 2014 a las 18:17

  • Para mí, no fue nada especial, solo una coma adicional al final del elemento de un objeto. Para llevar: cualquier cosa que haga que su JSON sea inconsistente, arrojará un error. Consejo extra: no confíes en jsonviewer.stack.hu Usa algo como jsonlint

    – Aman Alam

    24/10/2016 a las 11:30

esto funcionó para mí

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );

  • Utilicé esto y obtuve la matriz, pero los caracteres específicos de mi idioma (ş, ç, ö, ..) también se eliminaron.

    – zkanoca

    17 de diciembre de 2014 a las 10:56

  • Esto no es correcto si los datos json están codificados en UTF-8 (o cualquier codificación UTF, supongo). Eliminará los datos codificados en UTF-8 válidos. Probablemente funcionará siempre que el archivo solo contenga el idioma inglés, pero siempre es una suposición arriesgada. Yo no usaría esto.

    – Dédalo Alfa

    13/10/2015 a las 15:28

  • Con esto funciona, pero sin él no, aunque las dos cadenas son idénticas, ¿me estoy perdiendo algo?

    –Rudie Visser

    25 de agosto de 2016 a las 10:03


  • funciona! ¿pero por qué? la cadena que traté de decodificar no tenía caracteres especiales

    – Tobías Gassmann

    3 oct 2017 a las 13:19


Avatar de usuario de Pekka
Peka

Podría ser la codificación de los caracteres especiales. podrías preguntar json_último_error() para obtener información precisa.

  • He estado usando los caracteres especiales desde que inicié la aplicación y no hubo problemas antes. Localmente, la decodificación JSON funciona perfectamente. En mi servidor, no lo hace. y no puedo llamar json_last_error() porque es PHP 5.2.9. Esa función aparece en PHP 5.3.0.

    – Joel A. Villarreal Bertoldi

    9 de marzo de 2010 a las 15:54

  • No, esto debería funcionar. No puedo hacer más pruebas en este momento, si lo hago más tarde lo publicaré aquí. También hay algunos consejos en las notas aportadas por los usuarios: de.php.net/json_decode tal vez algo ayude

    – Peka

    9 de marzo de 2010 a las 16:09


  • Para mí, en PHP 5.3, funciona bien cuando el texto está codificado en UTF-8. Pero si paso el texto utf8_decode() primero luego json_decode() falla en silencio.

    – Mateo

    9 de marzo de 2010 a las 16:15

  • @Pekka Buscando respuestas en Google, volví a SO: stackoverflow.com/questions/689185/json-decode-returns-null-php. Mi archivo JSON tenía la secuencia UTF BOM (algunos caracteres binarios que no deberían estar allí), rompiendo así la estructura JSON. Fui a Hex Editor, borré los bytes. Todo ha vuelto a la normalidad. ¿Por qué ha sucedido esto? Porque edité el archivo usando el Bloc de notas de Micro$oft Windows. ¡Terrible idea!

    – Joel A. Villarreal Bertoldi

    9 de marzo de 2010 a las 17:59

  • Esto debe informarse como un error a la gente de PHP. Si la lista de materiales era UTF8 válida, no debería ahogarse en silencio.

    – jmucchiello

    9 de marzo de 2010 a las 18:34

Podrías intentarlo.

json_decode(stripslashes($_POST['data']))

avatar de usuario de user2254008
usuario2254008

Si verifica la solicitud en Chrome, verá que el JSON es texto, por lo que se agregó un código en blanco al JSON.

Puedes borrarlo usando

$k=preg_replace('/\s+/', '',$k);

Entonces puedes usar:

json_decode($k)

print_r luego mostrará la matriz.

Tal vez algunos personajes ocultos estén jugando con tu json, prueba esto:

$json = utf8_encode($yourString);
$data = json_decode($json);

Avatar de usuario de Charles Yapp
charles yap

Tuve el mismo problema y lo resolví simplemente reemplazando el carácter de comillas antes de decodificar.

$json = str_replace('"', '"', $json);
$object = json_decode($json);

Mi valor JSON fue generado por la función JSON.stringify.

Avatar de usuario de Enrico Tempesti
Enrico Tempesti

esto te ayuda a entender cuál es el tipo de error

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

  • Desde PHP 5.5.0 puedes usar el método json_last_error_msg para obtener un mensaje algo útil

    – Tomás Cuna

    7 abr 2021 a las 14:54

¿Ha sido útil esta solución?