2010-02-27 13 views
36

Estoy tratando de manejar los datos mal JSON cuando se analiza a través de json_decode(). Estoy usando el siguiente script:Detecta datos json malos en PHP json_decode()?

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

Si $ _POST es igual a:

'{ bar: "baz" }' 

Entonces json_decode maneja la multa de error y escupe; "datos JSON malas!" Sin embargo, si fijo $ _POST a algo así 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! 

¿Es necesario escribir una secuencia de comandos personalizada para detectar datos JSON válidos, o hay alguna otra manera ingeniosa para detectar ¿esta?

+0

'$ _POST' es siempre una matriz C mantener los parámetros * x-www-form-urlencoded * aprobados a través de POST. ¿Cómo envías tus datos a tu script PHP? – Gumbo

+0

Las funciones json incluidas en PHP no son de mucha ayuda. Ellos tienen muchos problemas. Eche un vistazo a [json.org] (http://json.org/) para encontrar una buena biblioteca. – whiskeysierra

Respuesta

82

Aquí hay un par de cosas sobre json_decode:

  • devuelve los datos, o null cuando hay un error
  • también puede volver null cuando no hay error: cuando la cadena JSON contiene null
  • se lanza una advertencia donde hay una advertencia - advertencia que quiere hacer desaparecer.


Para resolver el problema de la advertencia, una solución sería utilizar el @ operator(No suelo recomendar su uso, ya que hace debuging mucho más difícil ... Pero aquí, no existe mucho de una elección):

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

te había entonces tiene que probar si es $datanull - y, para evitar el caso en el que json_decode vuelve null para null en la cadena JSON, usted podría c diablos json_last_error, que (citando):

Devuelve el último error (si los hay) se produjo por última análisis JSON.


Lo que significa que tendría que usar un código como el siguiente:

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

También puede utilizar json_last_error: http://php.net/manual/en/function.json-last-error.php

que, como la documentación dice:

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

aquí es un ejemplo

+6

Esto es completamente innecesario en PHP 5.5 con http://php.net/manual/en/function.json-last-error-msg.php – vvondra

1

acabo de romper la cabeza por un error de sintaxis JSON en lo que parecía ser JSON perfecta: { "test1": "coche", "test2": "auto "} desde una cadena codificada en url.

Pero en mi caso, algunos de los anteriores fueron codificados 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)))); 

Esperemos que esto le ahorrará a alguien más algo de tiempo.

1

/** * * * json_decode encargo errores mango json_decode * * Tipo de @param $ json_text * @return tipo */ función pública custom_json_decode estática ($ 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' 
      ); 
    } 
} 
1

Esta es la forma en 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; 
}