454 votes

La façon la plus rapide de vérifier si une chaîne est du JSON en PHP?

J'ai besoin d'une méthode vraiment, vraiment rapide pour vérifier si une chaîne est en JSON ou non. J'ai l'impression que ce n'est pas la meilleure façon de le faire :

function isJson($string) {
    return ((is_string($string) &&
            (is_object(json_decode($string)) ||
            is_array(json_decode($string))))) ? true : false;
}

Des passionnés de performance veulent-ils améliorer cette méthode ?

3 votes

Considérez uniquement utiliser json_decode une seule fois... aussi, vérifiez les valeurs d'entrée et de retour de json_decode.

6 votes

Alors, laquelle est la réponse?

11 votes

Le commutateur ternaire ici est redondant. Votre déclaration évalue déjà comme un booléen.

667voto

Henrik P. Hessel Points 22046
fonction isJson($string) {
   json_decode($string);
   retourner json_last_error() === JSON_ERROR_NONE;
}

Solution PHP >= 8.3 :

utiliser fonction intégré json_validate()

22 votes

On dirait que tout le monde adore cette réponse. Une explication possible?

8 votes

Je crois que PHP 5.3 > est nécessaire pour utiliser la fonction json_last_error.

2 votes

Je pense que c'est bon car cela ne repose pas sur des heuristiques, utilise la fonctionnalité native de PHP et est à peu près aussi protégé contre l'avenir que vous puissiez obtenir; il vous dit simplement s'il y a eu des erreurs dans le décodage de la chaîne. Pas d'erreurs => JSON valide.

192voto

Madan Sapkota Points 3464

Réponse à la question

La fonction json_last_error renvoie la dernière erreur survenue lors de l'encodage et du décodage JSON. Ainsi, la manière la plus rapide de vérifier le JSON valide est

// décoder les données JSON
// définir le deuxième paramètre booléen TRUE pour une sortie de tableau associatif.
$result = json_decode($json);

if (json_last_error() === JSON_ERROR_NONE) {
    // JSON est valide
}

// OU c'est équivalent

if (json_last_error() === 0) {
    // JSON est valide
}

Notez que json_last_error est supporté uniquement dans PHP >= 5.3.0.

Programme complet pour vérifier l'ERREUR exacte

Il est toujours bon de connaître l'erreur exacte pendant le développement. Voici un programme complet pour vérifier l'erreur exacte basé sur la documentation PHP.

function json_validate($string)
{
    // décoder les données JSON
    $result = json_decode($string);

    // switch et vérifier les erreurs JSON possibles
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            $error = ''; // JSON est valide // Aucune erreur ne s'est produite
            break;
        case JSON_ERROR_DEPTH:
            $error = 'La profondeur maximale de la pile a été dépassée.';
            break;
        case JSON_ERROR_STATE_MISMATCH:
            $error = 'JSON invalide ou malformé.';
            break;
        case JSON_ERROR_CTRL_CHAR:
            $error = 'Erreur de caractère de contrôle, peut-être encodé de manière incorrecte.';
            break;
        case JSON_ERROR_SYNTAX:
            $error = 'Erreur de syntaxe, JSON malformé.';
            break;
        // PHP >= 5.3.3
        case JSON_ERROR_UTF8:
            $error = 'Caractères UTF-8 mal formés, peut-être encodés de manière incorrecte.';
            break;
        // PHP >= 5.5.0
        case JSON_ERROR_RECURSION:
            $error = 'Une ou plusieurs références récursives dans la valeur à encoder.';
            break;
        // PHP >= 5.5.0
        case JSON_ERROR_INF_OR_NAN:
            $error = 'Une ou plusieurs valeurs NAN ou INF dans la valeur à encoder.';
            break;
        case JSON_ERROR_UNSUPPORTED_TYPE:
            $error = 'Une valeur d'un type qui ne peut pas être encodé a été donnée.';
            break;
        default:
            $error = 'Une erreur JSON inconnue s\'est produite.';
            break;
    }

    if ($error !== '') {
        // générer l'exception ou quitter // ou autre chose :)
        exit($error);
    }

    // tout va bien
    return $result;
}

Test avec une ENTRÉE JSON valide

$json = '[{"user_id":13,"username":"stack"},{"user_id":14,"username":"over"}]';
$output = json_validate($json);
print_r($output);

Sortie valide

Array
(
    [0] => stdClass Object
        (
            [user_id] => 13
            [username] => stack
        )

    [1] => stdClass Object
        (
            [user_id] => 14
            [username] => over
        )
)

Test avec un JSON invalide

$json = '{background-color:yellow;color:#000;padding:10px;width:650px;}';
$output = json_validate($json);
print_r($output);

Sortie invalide

Erreur de syntaxe, JSON malformé.

Note supplémentaire pour (PHP >= 5.2 && PHP < 5.3.0)

Étant donné que json_last_error n'est pas pris en charge dans PHP 5.2, vous pouvez vérifier si l'encodage ou le décodage renvoie un booléen FALSE. Voici un exemple

// décoder les données JSON
$result = json_decode($json);
if ($result === FALSE) {
    // JSON est invalide
}

0 votes

Petite précision : si ce json est valide mais un précédent décrypté est invalide, votre code fonctionnera correctement, car : "Renvoie la dernière erreur (le cas échéant) survenue pendant le dernier encodage/décodage JSON."

0 votes

Merci @Madan, la vérification "json_decode" m'a permis de constater que j'utilise PHP 7.0.

0 votes

Il est possible que json_decode renvoie simplement false pour le littéral false, donc une vérification ((strlen($json) === 5) && ($json !== 'false')) devrait également être effectuée pour éviter cette situation ?

93voto

user1653711 Points 147

Tout ce que vous avez vraiment besoin de faire est cela...

if (is_object(json_decode($MyJSONArray))) 
{ 
    ... faire quelque chose ...
}

Cette requête ne nécessite même pas une fonction séparée. Il suffit d'envelopper is_object autour de json_decode et de continuer. Il semble que cette solution fait réfléchir les gens beaucoup trop.

3 votes

@RomanM.Kos Juste pour être clair, si le tableau est un tableau simple, alors vous devez utiliser is_array en plus de is_object, sinon is_object renverra faux pour les tableaux simples encodés en JSON. Ainsi @ggutenberg a raison dans ce cas. Passer l'argument true à json_decode force un objet à être renvoyé en tant que tableau. En théorie, vous pourriez toujours forcer le décodage en tableau et simplement vérifier is_array, cela devrait fonctionner.

0 votes

@userabuser Si je json_encode($array) pour un tableau PHP simple, puis fais json_decode($str), je recevrai un objet, mais pas un tableau. json_decode($str, true) force la conversion en tableau. Pourquoi compliquer la chaîne dans votre code? Vérifiez is_array(json_decode($str, true)) et quelques temps après, lorsque vous le lisez, vous comprendrez que le décodé doit être uniquement un tableau. Beaucoup plus difficile de deviner is_object(json_decode($MyJSONArray)) "Oh, ici je vérifie si le décodé est un tableau ou non?"

0 votes

@RomanM.Kos Non, ce n'est pas correct, codepad.viper-7.com/OFrtsq - comme je l'ai dit, vous pouvez toujours forcer json_decode à retourner un tableau pour vous éviter de vérifier l'objet et le tableau, mais si vous ne le faites pas ET vous json_decode ce qui était un simple tableau au départ, vous recevrez en retour un tableau décodé, pas un objet. Vous devez utiliser JSON_FORCE_OBJECT si vous voulez toujours forcer un objet sur l'encodage SI vous passez un simple tableau.

76voto

mario Points 76989

Utiliser json_decode pour le "sonder" pourrait ne pas être la manière la plus rapide. S'il s'agit d'une structure profondément imbriquée, instancier beaucoup d'objets ou de tableaux pour ensuite les jeter est une perte de mémoire et de temps.

Il peut donc être plus rapide d'utiliser preg_match et l'regex RFC4627 pour également assurer la validité:

  // en JS:
  var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
         texte.replace(/"(\\.|[^"\\])*"/g, '')));

Le même en PHP:

  return !preg_match('/[^,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t]/',
       preg_replace('/"(\\.|[^"\\\\])*"/', '', $json_string));

Je ne suis pas assez enthousiaste de la performance pour m'embêter avec des benchmarks ici cependant.

0 votes

Grande idée, je comprends que cela ne vérifie que la validité (toutes les chaînes sont incluses dans des chaînes) et pas la syntaxe correcte.

0 votes

Il s'agit en fait davantage d'une vérification d'invalidité et contre les attaques JS. Vérifier la structure nécessiterait une expression régulière plus élaborée (?R), faisable, mais apparemment personne n'a encore essayé.

0 votes

C'est en effet la meilleure façon d'essayer avant de passer par une séquence d'échecs brute pour déterminer ce qu'il est vraiment. Cela a aussi (partiellement) répondu à ma question.

22voto

ahmet alp balkan Points 7264
function is_json($str){ 
    return json_decode($str) != null;
}

http://tr.php.net/manual/fr/function.json-decode.php la valeur de retour est null lorsque l'encodage invalide est détecté.

4 votes

Il renverra également de manière incorrecte null pour "null" (ce qui n'est pas un JSON valide, mais peut-être entièrement "valide" pour json_decode autrement). Allez comprendre.

0 votes

Je pense que cela devrait être : json_decode($str)! = null; ou sinon la fonction devrait être appelée is_not_json.

0 votes

Cette fonction serait mieux renommée en "est autre chose que du JSON" !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X