PHP json кодирует кодирующие числа в виде строк


У меня возникла одна проблема с функцией PHP json_encode. Он кодирует числа в виде строк, например

array('id' => 3)

Становится

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

Когда js обнаруживает эти значения, он интерпретирует их как строки, и числовые операции с ними завершаются неудачей. Кто-нибудь знает какой-нибудь способ запретить json_encode кодировать числа в виде строк? Спасибо!

Author: Gottlieb Notschnabel, 2009-09-08

17 answers

Я провел очень быстрый тест:

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

Похоже, это похоже на то, что вы описываете, если я не ошибаюсь?

И я получаю в качестве вывода:

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

Таким образом, в данном случае целые числа не были преобразованы в строку.


Тем не менее, это может зависеть от версии PHP, которую мы используем: было исправлено несколько ошибок, связанных с json_encode, в зависимости от версии PHP...

Этот тест был выполнен с помощью PHP 5.2.6; Я получаю то же самое с PHP 5.2.9 и 5.3.0; У меня нет другой версии 5.2.x для тестирования, хотя:-(

Какую версию PHP вы используете? Или ваш тестовый случай сложнее, чем опубликованный вами пример?

Возможно, одно сообщение об ошибке в http://bugs.php.net / может быть связано? Например, Ошибка #40503: преобразование целых чисел json_encode несовместимо с PHP ?


Может быть, Ошибка #38680 вас тоже заинтересует, кстати?

 25
Author: Pascal MARTIN, 2009-09-07 21:50:39

Обратите внимание, что начиная с PHP 5.3.3, существует флаг для автоматического преобразования чисел (параметр options был добавлен в PHP 5.3.0):

$arr = array( 'row_id' => '1', 'name' => 'George' );
echo json_encode( $arr, JSON_NUMERIC_CHECK ); // {"row_id":1,"name":"George"}
 291
Author: Rijk, 2015-12-21 15:29:59

Я тоже читал из БД (PostgreSQL), и все было строкой. Мы перебираем каждую строку и делаем с ней что-то, чтобы создать наш массив конечных результатов, поэтому я использовал

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

В цикле, чтобы заставить его быть целочисленным значением. Когда я делаю json_encode($result_arr) сейчас, он правильно форматирует его как число. Это позволяет вам контролировать, что является, а что нет номером, поступающим из вашей базы данных.

ИЗМЕНИТЬ:

Функция json_encode() также имеет возможность делать это на лету, используя JSON_NUMERIC_CHECK флаг в качестве второго аргумента к нему. Вам нужно быть осторожным, используя его, как показано в этом примере пользователей в документации (скопировано ниже): http://uk3.php.net/manual/en/function.json-encode.php#106641

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

И затем вы получаете этот JSON:

{"phone_number":33123456789}
 32
Author: mouckatron, 2014-01-15 12:43:15

Я сталкиваюсь с той же проблемой (PHP-5.2.11/Windows). Я использую этот обходной путь

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

, который заменяет все (неотрицательные, целочисленные) числа, заключенные в кавычки, самим числом ('"42"' становится '42').

Смотрите также этот комментарий в руководстве по PHP.

 8
Author: oli_arborum, 2010-03-10 13:53:37

Попробуйте $arr = array('var1' => 100, 'var2' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);

Но это работает только на PHP 5.3.3. Посмотрите на этот журнал изменений PHP json_encode http://php.net/manual/en/function.json-encode.php#refsect1-function.json-encode-changelog

 7
Author: habibillah, 2011-10-29 11:47:36

Следующий тест подтверждает, что изменение типа на string приводит к тому, что функция json_encode() возвращает числовое значение в виде строки JSON (т. Е. в двойных кавычках). Используйте settype (arr["var"], "целое число") или settype ($arr["var"], "float"), чтобы исправить это.

<?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
Author: Jay Andrew Allen, 2010-10-13 07:31:43

Для полноты картины (поскольку я пока не могу добавлять комментарии) позвольте мне также добавить эту деталь в качестве другого ответа:

(Редактировать: Следует прочитать после осознания того, что исходные данные (т. Е. в случае операции, результирующий набор базы данных) могут быть проблемой (возвращая числовые столбцы в виде строк), а json_encode() на самом деле не был источником проблемы)

Справочные страницы обоих "mysql_fetch_array":

Возвращает массив строк , соответствующий выбранная строка,

... и "строка mysql_ fetch_":

Возвращает числовой массив строк , соответствующий выбранной строке

Четко указывает, что; записи в возвращаемом массиве будут строками.

(Я использовал класс DB в phpBB2 (да, я знаю, он устарел!), и метод "sql_fetchrow()" этого класса использует "mysql_fetch_array()")

Не осознавая этого, я также нашел этот вопрос, и понимание проблемы!:)

Как Паскаль Мартин заявил выше в своих последующих комментариях, я считаю, что решение, которое решает проблему "неправильного типа" в источнике (т.Е. с помощью функции "mysql_field_type()" и выполняет приведение сразу после выборки (или других методов выборки, таких как "объект"?)), в целом было бы лучше.

 1
Author: OzgurH, 2011-10-28 08:13:58

Итак, Паскаль МАРТИН не получает здесь достаточного признания. Проверка числовых значений при каждом возврате JSON невозможна для существующего проекта с сотнями функций на стороне сервера.

Я заменил php-mysql на php-mysqlnd, и проблема исчезла. Числа - это числа, строки - это строки, логические значения - это логические значения.

 1
Author: Rory Jarrard, 2018-02-15 16:25:44

У меня также была такая же проблема с обработкой данных из базы данных. В основном проблема заключается в том, что тип в массиве для преобразования в json распознается PHP как строка, а не как целое число. В моем случае я сделал запрос, который возвращает данные из строки подсчета столбцов БД. Драйвер PDO распознает столбец не как int, а как строки. Я решил проблему, выполнив приведение как int в соответствующем столбце.

 0
Author: balucio, 2011-06-13 11:11:58
$rows = array();
while($r = mysql_fetch_assoc($result)) {
    $r["id"] = intval($r["id"]); 
    $rows[] = $r;
}
print json_encode($rows);  
 0
Author: Yar, 2013-11-13 15:03:15

Проблема в версии php, если бы та же проблема обновила мою версию php до 5.6, проблема была решена

 0
Author: Peter Allen, 2017-04-03 23:13:31

Приведение значений к значению int или float, похоже, исправляет это. Например:

$coordinates => array( 
    (float) $ap->latitude,
    (float) $ap->longitude 
);
 0
Author: Derrick Miller, 2017-05-23 19:51:07

Вы можете использовать (int), если возникнет какая-либо проблема!! Это будет работать нормально.

 0
Author: Rahul Gupta, 2017-08-02 06:21:26

Ну, PHP json_encode() возвращает строку.

Вы можете использовать parseFloat() или parseInt() в коде js, хотя:

parseFloat('122.5'); // returns 122.5
parseInt('22'); // returns 22
parseInt('22.5'); // returns 22
 -1
Author: Richard Knop, 2009-09-07 21:19:02

Просто столкнулся с той же проблемой, и база данных возвращала значения в виде строк.

Я использую это как обходной путь:

$a = array(
    'id' => $row['id'] * 1,
    'another' => ...,
    'ananother' => ...,
);
$json = json_encode($a);

То есть умножаем значение на 1, чтобы преобразовать его в число

Надеюсь, это кому-то поможет

 -1
Author: Leon, 2014-01-07 15:07:55

Json_encode сериализует некоторую структуру данных в формате JSON для отправки по сети. Поэтому все содержимое будет иметь тип string. Точно так же, как когда вы получаете какой-то параметр от $_POST или $_GET.

Если вам нужно выполнить числовые операции над отправленными значениями, просто сначала преобразуйте их в int (с помощью функции intval() в PHP или parseInt() в Javascript), а затем выполните операции.

 -2
Author: rogeriopvl, 2009-09-07 21:18:56

Как сказал оли_арборум, я думаю, что вы можете использовать preg_replace для выполнения этой работы. Просто измените команду следующим образом:

$json = preg_replace('#:"(\d+)"#', ':$1', $json);
 -2
Author: Santini Arnaud, 2015-05-31 01:59:58