web-dev-qa-db-fra.com

PHP json_encode encodant des nombres sous forme de chaînes

J'ai un problème avec la fonction PHP json_encode. Elle code les nombres sous forme de chaînes, p. Ex.

array('id' => 3)

devient

"{ ["id": "3", ...)

Lorsque js rencontre ces valeurs, il les interprète comme des chaînes et les opérations numériques échouent. Est-ce que quelqu'un sait un moyen d'empêcher json_encode de coder des nombres sous forme de chaînes? Je vous remercie!

131
Chris Barnhill

J'ai fait un test très rapide:

$a = array(
    'id' => 152,
    'another' => 'test',
    'ananother' => 456,
);
$json = json_encode($a);
echo $json;

Cela ressemble à ce que vous décrivez, si je ne me trompe pas?

Et je reçois en sortie:

{"id":152,"another":"test","ananother":456}

Donc, dans ce cas, les entiers n'ont pas été convertis en chaîne.


Néanmoins, cela pourrait dépendre de la version de PHP que nous utilisons: quelques bogues liés à json_encode ont été corrigés, en fonction de la version de PHP ...

Ce test a été fait avec PHP 5.2.6; je reçois la même chose avec PHP 5.2.9 et 5.3.0; je ne avoir une autre version 5.2.x à tester, cependant :

Quelle version de PHP utilisez-vous? Ou votre test-case est-il plus complexe que l'exemple que vous avez posté?

Peut-être qu'un rapport de bogue sur --- (http://bugs.php.net/ pourrait être lié? Par exemple, Bogue n ° 40503: la conversion de nombre entier json_encode est incompatible avec PHP ?


Peut-être que bug # 3868 pourrait vous intéresser aussi, d'ailleurs?

28
Pascal MARTIN

Notez que depuis PHP 5.3.3, il y a un drapea pour la conversion automatique des nombres (le paramètre options a été ajouté dans PHP 5.3 .0):

$arr = array( 'row_id' => '1', 'name' => 'George' );
echo json_encode( $arr, JSON_NUMERIC_CHECK ); // {"row_id":1,"name":"George"}
322
Rijk

De même, je lisais à partir d'une base de données (PostgreSQL) et tout était une chaîne. Nous passons en boucle sur chaque ligne et faisons des choses avec pour construire notre tableau de résultats finaux, alors j’ai utilisé

$result_arr[] = array($db_row['name'], (int)$db_row['count']);

dans la boucle pour le forcer à être une valeur entière. Quand je fais json_encode($result_arr) maintenant, il le formate correctement en tant que nombre. Cela vous permet de contrôler ce qui est ou non un nombre provenant de votre base de données.

MODIFIER:

La fonction json_encode() a également la capacité de le faire à la volée en utilisant le drapeau JSON_NUMERIC_CHECK Comme second argument. Vous devez cependant faire attention en l'utilisant comme indiqué dans cet exemple d'utilisateur dans la documentation (copie ci-dessous): http://uk3.php.net/manual/fr/function.json-encode.php#106641

<?php
// International phone number
json_encode(array('phone_number' => '+33123456789'), JSON_NUMERIC_CHECK);
?>

Et puis vous obtenez ce JSON:

{"phone_number":33123456789}
33
mouckatron

Je rencontre le même problème (PHP 5.2.11/Windows). J'utilise cette solution de contournement

$json = preg_replace( "/\"(\d+)\"/", '$1', $json );

qui remplace tous les nombres (non négatifs, entiers) entre guillemets par le nombre lui-même ("" 42 "" devient "42").

Voir aussi ce commentaire dans PHP manuel .

8
oli_arborum

essayez $arr = array('var1' => 100, 'var2' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);

Mais cela fonctionne simplement sur PHP 5.3.3. Regardez ceci PHP json_encode change log --- http://php.net/manual/en /function.json-encode.php#refsect1-function.json-encode-changelog

7
habibillah

Le test suivant confirme que, si vous modifiez le type en chaîne, json_encode () renvoie un nombre sous forme de chaîne JSON (c'est-à-dire entourée de guillemets). Utilisez settype (arr ["var"], "entier") ou settype ($ arr ["var"], "float") pour résoudre ce problème.

<?php

class testclass {
    public $foo = 1;
    public $bar = 2;
    public $baz = "Hello, world";
}

$testarr = array( 'foo' => 1, 'bar' => 2, 'baz' => 'Hello, world');

$json_obj_txt = json_encode(new testclass());
$json_arr_txt = json_encode($testarr);

echo "<p>Object encoding:</p><pre>" . $json_obj_txt . "</pre>";
echo "<p>Array encoding:</p><pre>" . $json_arr_txt . "</pre>";

// Both above return ints as ints. Type the int to a string, though, and...
settype($testarr["foo"], "string");
$json_arr_cast_txt = json_encode($testarr);
echo "<p>Array encoding w/ cast:</p><pre>" . $json_arr_cast_txt . "</pre>";

?>
3
Jay Andrew Allen

Donc Pascal MARTIN n’obtient pas assez de crédit ici. La vérification de valeurs numériques sur chaque retour JSON n'est pas réalisable pour un projet existant comportant des centaines de fonctions côté serveur.

J'ai remplacé php-mysql par php-mysqlnd, et le problème a disparu. Les nombres sont des nombres, les chaînes sont des chaînes, les booléens sont des booléens.

2
Rory Jarrard

Par souci d'exhaustivité (je ne peux pas encore ajouter de commentaires), permettez-moi d'ajouter ce détail comme une autre réponse:

(Édition: à lire après avoir réalisé que les données source (c'est-à-dire, dans le cas du PO, résultat de la base de données) pourraient être le problème (en renvoyant des colonnes numériques sous forme de chaînes), et json_encode () n'était en fait pas la source du problème)

Pages de manuel des deux " mysql_fetch_array ":

Retourne un tableau de chaînes qui correspond à la ligne lue,

... et " mysql_fetch_ row ":

Retourne un tableau numérique de chaînes qui correspond à la ligne lue

indique clairement que; les entrées dans le tableau retourné seront des chaînes.

(J'utilisais la classe DB dans phpBB2 (oui, c'est obsolète!), Et la méthode "sql_fetchrow ()" de cette classe utilise "mysql_fetch_array ()")

Ne réalisant pas cela, j'ai aussi fini par trouver cette question et comprendre le problème! :)

Comme Pascal Martin l'a dit plus haut dans ses commentaires de suivi, je pense qu'une solution prend en charge le problème du "type incorrect" à la source (en utilisant la fonction " mysql_field_type () " et en effectuant les opérations suivantes: lancer juste après l'extraction, (ou d'autres méthodes d'extraction telles que "objet"?)) serait mieux en général.

2
OzgurH

J'ai également eu le même problème de traitement des données de la base de données. En gros, le problème est que le type du tableau à convertir en json est reconnu par PHP comme une chaîne et non comme un entier. Dans mon cas, j’ai effectué une requête qui renvoie les données d’une colonne de la base de données. ligne de comptage. Le pilote PDO ne reconnaît pas la colonne en tant qu'int, mais en tant que chaînes. J'ai résolu ce problème en effectuant une conversion en tant que int dans la colonne concernée.

0
balucio

Vous pouvez utiliser (int) si un problème survient !! Cela fonctionnera bien.

0
Rahul Gupta
$rows = array();
while($r = mysql_fetch_assoc($result)) {
    $r["id"] = intval($r["id"]); 
    $rows[] = $r;
}
print json_encode($rows);  
0
Yar

il est version php le problème, avait le même problème mis à niveau ma version php à 5.6 résolu le problème

0
Peter Allen

Lancer les valeurs sur un int ou un float semble résoudre le problème. Par exemple:

$coordinates => array( 
    (float) $ap->latitude,
    (float) $ap->longitude 
);
0
Derrick Miller