utf8 - PHP json_encode codificando números como cadenas
string to json php (17)
Tengo un problema con la función PHP json_encode. Codifica los números como cadenas, por ejemplo
array(''id'' => 3)
se convierte
"{ ["id": "3", ...)
Cuando js encuentra estos valores, los interpreta como cadenas y las operaciones numéricas fallan en ellos. ¿Alguien sabe alguna forma de evitar que json_encode
codifique números como cadenas? ¡Gracias!
¡Puedes usar (int) si ocurre algún problema! Funcionará bien.
Bueno, PHP json_encode () devuelve una cadena.
Sin embargo, puedes usar parseFloat () o parseInt () en el código js:
parseFloat(''122.5''); // returns 122.5
parseInt(''22''); // returns 22
parseInt(''22.5''); // returns 22
Como dijo oli_arborum, creo que puedes usar un preg_replace
para hacer el trabajo. Simplemente cambie el comando de esta manera:
$json = preg_replace(''#:"(/d+)"#'', '':$1'', $json);
En aras de la exhaustividad (ya que no puedo agregar comentarios todavía), permítanme agregar este detalle como otra respuesta:
(Editar: para leer después de darse cuenta de que los datos fuente (es decir, en el caso del OP, conjunto de resultados de la base de datos) podrían ser el problema (devolviendo columnas numéricas como cadenas), y json_encode () de hecho no era la fuente del problema)
Paginas manuales de ambos " mysql_fetch_array ":
Devuelve una matriz de cadenas que corresponde a la fila recuperada
... y " mysql_ fetch_ row ":
Devuelve una matriz numérica de cadenas que corresponde a la fila recuperada
dice claramente eso; las entradas en la matriz devuelta serán cadenas.
(Estaba usando la clase DB en phpBB2 (sí, lo sé, ¡está obsoleta!), Y el método "sql_fetchrow ()" de esa clase usa "mysql_fetch_array ()"
Sin darme cuenta de eso, también terminé encontrando esta pregunta y entendiendo el problema. :)
Como dijo Pascal Martin arriba en sus comentarios de seguimiento, creo que una solución que soluciona el problema del "tipo incorrecto" en la fuente (es decir, usando la función " mysql_field_type() " y haciendo el casting justo después de buscar, (o otros métodos de búsqueda como "objeto"?)) sería el mejor en general.
Entonces no está recibiendo suficiente crédito aquí. La comprobación de valores numéricos en cada devolución JSON no es factible para un proyecto existente con cientos de funciones del lado del servidor.
Reemplacé php-mysql con php-mysqlnd, y el problema desapareció. Los números son números, las cadenas son cadenas, los booleanos son booleanos.
He hecho una prueba muy rápida:
$a = array(
''id'' => 152,
''another'' => ''test'',
''ananother'' => 456,
);
$json = json_encode($a);
echo $json;
Esto parece ser como lo que describes, si no me equivoco?
Y estoy obteniendo como salida:
{"id":152,"another":"test","ananother":456}
Entonces, en este caso, los enteros no se han convertido en cadena.
Aún así, esto podría depender de la versión de PHP que estamos usando: se han corregido un par de errores relacionados con json_encode, dependiendo de la versión de PHP ...
Esta prueba se ha realizado con PHP 5.2.6; Estoy obteniendo lo mismo con PHP 5.2.9 y 5.3.0; No tengo otra versión 5.2.x para probar, aunque :-(
¿Qué versión de PHP estás usando? ¿O su caso de prueba es más complejo que el ejemplo que publicó?
Tal vez un informe de error en http://bugs.php.net/ podría estar relacionado? Por ejemplo, la conversión de número entero Bug # 40503: json_encode es inconsistente con PHP ?
Tal vez Bug # 38680 podría interesarle también, ¿cierto?
La siguiente prueba confirma que al cambiar el tipo a cadena, json_encode () devuelve un número como cadena JSON (es decir, rodeado por comillas dobles). Use settype (arr ["var"], "integer") o settype ($ arr ["var"], "float") para arreglarlo.
<?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>";
?>
Lanzar los valores a un int o float parece arreglarlo. Por ejemplo:
$coordinates => array(
(float) $ap->latitude,
(float) $ap->longitude
);
Me encuentro con el mismo problema (PHP-5.2.11 / Windows). Estoy usando esta solución
$json = preg_replace( "//"(/d+)/"/", ''$1'', $json );
que reemplaza todos los números (no negativos, enteros) entre comillas con el número mismo (''"42"'' se convierte en ''42'').
Ver también este comentario en el manual de PHP .
Solo encontré el mismo problema y fue la base de datos que devolvió los valores como cadenas.
Yo uso esto como una solución alternativa:
$a = array(
''id'' => $row[''id''] * 1,
''another'' => ...,
''ananother'' => ...,
);
$json = json_encode($a);
Eso es multiplicar el valor por 1 para convertirlo en un número
Espero que ayude a alguien
También tuve el mismo problema al procesar los datos de la base de datos. Básicamente, el problema es que el tipo en la matriz para convertir en json, es reconocido por PHP como una cadena y no como un entero. En mi caso, hice una consulta que devuelve datos de una fila de conteo de columna DB. El controlador PDO no reconoce la columna como int, sino como cadenas. Lo resolví realizando un lanzamiento como int en la columna afectada.
Tenga en cuenta que desde PHP 5.3.3, hay un indicador para la auto conversión de números (el parámetro de opciones fue agregado en PHP 5.3.0):
$arr = array( ''row_id'' => ''1'', ''name'' => ''George'' );
echo json_encode( $arr, JSON_NUMERIC_CHECK ); // {"row_id":1,"name":"George"}
Yo también estaba leyendo de un DB (PostgreSQL) y todo era una cadena. Recorrimos cada fila y hacemos cosas con ella para construir nuestra matriz de resultados final, así que utilicé
$result_arr[] = array($db_row[''name''], (int)$db_row[''count'']);
dentro del ciclo para forzarlo a ser un valor entero. Cuando hago json_encode($result_arr)
ahora, lo formatea correctamente como un número. Esto le permite controlar qué es y qué no es un número proveniente de su base de datos.
EDITAR:
La función json_encode()
también tiene la capacidad de hacerlo sobre la marcha utilizando el indicador JSON_NUMERIC_CHECK
como segundo argumento. Sin embargo, debe tener cuidado al usarlo, como se muestra en este ejemplo de usuario en la documentación (copiado a continuación): http://uk3.php.net/manual/en/function.json-encode.php#106641
<?php
// International phone number
json_encode(array(''phone_number'' => ''+33123456789''), JSON_NUMERIC_CHECK);
?>
Y luego obtienes este JSON:
{"phone_number":33123456789}
el problema es la versión php, el mismo problema actualizó mi versión php a 5.6 resolvió el problema
json_encode serializa cierta estructura de datos en formato JSON para enviar a través de la red. Por lo tanto, todo el contenido será del tipo cadena. Al igual que cuando recibe algún parámetro de $ _POST o $ _GET.
Si tiene que realizar operaciones numéricas en los valores enviados, simplemente conviértalos a int primero (con la función intval () en PHP o parseInt () en Javascript) y luego ejecute las operaciones.
try $arr = array(''var1'' => 100, ''var2'' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);$arr = array(''var1'' => 100, ''var2'' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);
Pero solo funciona en PHP 5.3.3. Mire este PHP json_encode changelog http://php.net/manual/en/function.json-encode.php#refsect1-function.json-encode-changelog
$rows = array();
while($r = mysql_fetch_assoc($result)) {
$r["id"] = intval($r["id"]);
$rows[] = $r;
}
print json_encode($rows);