¿Detectar datos json incorrectos en PHP json_decode ()?

7 minutos de lectura

Estoy tratando de manejar datos json incorrectos cuando se analizan a través de json_decode(). Estoy usando el siguiente script:

if(!json_decode($_POST)) {
  echo "bad json data!";
  exit;
}

Si $_POST es igual a:

'{ bar: "baz" }'

Luego, json_decode maneja bien el error y escupe “¡datos json incorrectos!”; Sin embargo, si configuro $_POST en algo como “datos no válidos”, me da:

Warning: json_decode() expects parameter 1 to be string, array given in C:\server\www\myserver.dev\public_html\rivrUI\public_home\index.php  on line 6
bad json data!

¿Necesito escribir un script personalizado para detectar datos json válidos, o hay alguna otra forma ingeniosa de detectar esto?

  • $_POST es siempre una matriz que contiene el x-www-form-urlencoded parámetros pasados ​​a través de POST. ¿Cómo envía sus datos a su script PHP?

    – Gumbo

    27 de febrero de 2010 a las 16:58

  • Las funciones json incluidas en PHP no son de mucha ayuda. Tienen muchos problemas. Echa un vistazo a json.org encontrar una buena biblioteca.

    – whiskysierra

    27 de febrero de 2010 a las 17:02


Aquí hay un par de cosas sobre json_decode :

  • devuelve los datos, o null cuando hay un error
  • tambien puede volver null cuando no hay error: cuando la cadena JSON contiene null
  • genera una advertencia donde hay una advertencia, una advertencia que quieres hacer desaparecer.

Para resolver el problema de las advertencias, una solución sería usar el @ operador (No recomiendo usarlo a menudo, ya que hace que la depuración sea mucho más difícil… Pero aquí, no hay muchas opciones) :

$_POST = array(
    'bad data'
);
$data = @json_decode($_POST);

Entonces tendrías que probar si $data es null — y, para evitar el caso en que json_decode devoluciones null por null en la cadena JSON, puede verificar json_last_errorcual (citando) :

Devuelve el último error (si lo hay) que se produjo en el último análisis de JSON.

Lo que significa que tendrías que usar algún código como el siguiente:

if ($data === null
    && json_last_error() !== JSON_ERROR_NONE) {
    echo "incorrect data";
}

  • Como señaló Harry Bosch en otra respuesta, solo necesita verificar JSON_ERROR_NONE !== json_last_error()

    – etiqueta alternativa

    12 de abril de 2019 a las 2:13

También puedes usar json_last_error: http://php.net/manual/en/function.json-ultimo-error.php

que como documentación dice:

Devuelve el último error (si lo hubo) ocurrido durante la última codificación/descodificación JSON.

Aquí hay un ejemplo

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;
}

  • Esto es completamente innecesario en PHP 5.5 con php.net/manual/en/function.json-ultimo-error-msg.php

    – vvondra

    4 de marzo de 2015 a las 0:16

  • Podrías hacer algo como esto con json_last_error_msg: if (JSON_ERROR_NONE !== json_last_error()) throw new Exception(json_last_error_msg());

    – A1rPun

    3 sep 2019 a las 20:45

¿Detectar datos json incorrectos en PHP json decode
dtar

Desde PHP 7.3la función json_decode aceptará una nueva opción JSON_THROW_ON_ERROR que permitirá que json_decode genere una excepción en lugar de devolver un valor nulo en caso de error.


Ejemplo:

try {  
  json_decode("{", false, 512, JSON_THROW_ON_ERROR);  
}  
catch (\JsonException $exception) {  
  echo $exception->getMessage(); // displays "Syntax error"  
}

  • Esta debería ser la respuesta aceptada. JSON_THROW_ON_ERROR constante

    – A1rPun

    3 sep 2019 a las 20:48

  • Recibí una excepción: "Warning: Use of undefined constant JSON_THROW_ON_ERROR - assumed 'JSON_THROW_ON_ERROR' (this will throw an Error in a future version of PHP) in <file_path>

    – dom dambrogia

    28 de abril de 2020 a las 1:35

  • @domdambrogia La constante JSON_THROW_ON_ERROR solo está disponible desde PHP 7.3

    – David DIVERRES

    5 de noviembre de 2020 a las 15:25

  • no funciona en 7.3.24 el error está ahí pero no pudo detectarlo

    – Tom Sawyer

    10 oct 2021 a las 15:10

1646752993 940 ¿Detectar datos json incorrectos en PHP json decode
corredor de klompen

Me rompí la cabeza por un error de sintaxis json en lo que parecía ser un json perfecto: {"test1":"car", "test2":"auto"} de una cadena codificada de url.

Pero en mi caso, algo de lo anterior estaba codificado en html, como agregar html_entity_decode($string) Hizo el truco.

$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING))));

Con suerte, esto le ahorrará tiempo a alguien más.

Así es como Guzzle maneja json

    /**
 * Parse the JSON response body and return an array
 *
 * @return array|string|int|bool|float
 * @throws RuntimeException if the response body is not in JSON format
 */
public function json()
{
    $data = json_decode((string) $this->body, true);
    if (JSON_ERROR_NONE !== json_last_error()) {
        throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error());
    }

    return $data === null ? array() : $data;
}

1646752994 591 ¿Detectar datos json incorrectos en PHP json decode
Zet

Acabo de pasar una hora revisando todas las soluciones posibles en esta página. Me tomé la libertad de recopilar todas estas posibles soluciones en una funcionpara que sea más rápido y fácil de probar y depurar.

Espero que pueda ser de utilidad para alguien más.

<?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('/[\r\n\t ]+/', ' ', $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();
?>

Lo mantendré aquí: https://github.com/zethodderskov/decontaminate-text-in-php/blob/master/decontaminate-text-preparing-it-for-json-decode.php

¿Detectar datos json incorrectos en PHP json decode
Tomáš Fejfar

/**
 * 
 * custom json_decode 
 * handle json_decode errors
 * 
 * @param type $json_text
 * @return type
 */
public static function custom_json_decode($json_text) {

    $decoded_array = json_decode($json_text, TRUE);
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            return array(
                "status" => 0,
                "value" => $decoded_array
            );


        case JSON_ERROR_DEPTH:
            return array(
                "status" => 1,
                "value" => 'Maximum stack depth exceeded'
            );

        case JSON_ERROR_STATE_MISMATCH:
            return array(
                "status" => 1,
                "value" => 'Underflow or the modes mismatch'
            );

        case JSON_ERROR_CTRL_CHAR:
            return array(
                "status" => 1,
                "value" => 'Unexpected control character found'
            );

        case JSON_ERROR_SYNTAX:
            return array(
                "status" => 1,
                "value" => 'Syntax error, malformed JSON'
            );

        case JSON_ERROR_UTF8:
            return array(
                "status" => 1,
                "value" => 'Malformed UTF-8 characters, possibly incorrectly encoded'
            );

        default:
            return array(
                "status" => 1,
                "value" => 'Unknown error'
            );
    }
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad