2010-02-27 4 views
36

J'essaie de gérer les données json mauvaises lorsqu'elles sont analysées via json_decode(). J'utilise le script suivant:Détecter les données de mauvais json dans PHP json_decode()?

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

Si $ _POST est égal à:

'{ bar: "baz" }' 

Puis json_decode poignées l'amende d'erreur et crache, "mauvaises données JSON!" Cependant, si je mets $ _POST à ​​quelque chose comme « données non valide », il me donne:

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! 

Ai-je besoin d'écrire un script personnalisé pour détecter les données JSON valides, ou est-il un autre moyen astucieux pour détecter ce?

+0

'$ _POST' est toujours un tableau c contenant les paramètres * x-www-form-urlencoded * transmis via POST. Comment envoyez-vous vos données à votre script PHP? – Gumbo

+0

Les fonctions json incluses dans PHP ne sont pas beaucoup d'aide. Ils ont beaucoup de problèmes. Jetez un oeil à [json.org] (http://json.org/) pour trouver une bonne bibliothèque. – whiskeysierra

Répondre

82

Voici quelques choses sur json_decode:

  • il renvoie les données ou null quand il y a une erreur
  • il peut aussi revenir null quand il n'y a pas d'erreur: lorsque la chaîne JSON contient null
  • il déclenche un avertissement lorsqu'il y a un avertissement - avertissement que vous voulez faire disparaître.


Pour résoudre le problème d'alerte, une solution serait d'utiliser le @ operator(Je ne recommande pas souvent l'utiliser, car il rend debug beaucoup plus difficile ... Mais ici, il n'y a pas beaucoup de choix):

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

vous aurait alors à tester si $data est null - et, pour éviter le cas où json_decode retours null pour null dans la chaîne JSON, vous pourriez c Heck json_last_error, qui (citant):

Renvoie la dernière erreur (le cas échéant) se sont produits par la dernière analyse JSON.


Ce qui signifie que vous auriez à utiliser un code comme le suivant:

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

Vous pouvez également utiliser json_last_error: http://php.net/manual/en/function.json-last-error.php

qui, comme la documentation dit:

Renvoie la dernière erreur (le cas échéant) survenue lors du dernier JSON codage/décodage.

est ici un exemple

+6

Ceci est complètement inutile dans PHP 5.5 avec http://php.net/manual/fr/function.json-last-error-msg.php – vvondra

1

Je viens de me casser la tête sur une erreur de syntaxe JSON dans ce qui semblait être JSON parfaite: { "test1": "voiture", "test2": "auto "} à partir d'une chaîne codée par url.

Mais dans mon cas, certains des éléments ci-dessus ont été codés en HTML, car l'ajout de html_entity_decode($string) a fait l'affaire.

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

Espérons que cela sauvera quelqu'un d'autre.

1

/** * * json_decode personnalisé * gérer les erreurs de json_decode * * Type @param $ json_text * Type de @return */ public static function custom_json_decode (json_text de $) {

$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

Voici comment gère Guzzle 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; 
}