sunsey
@sunsey
Web dev

json_encode — строгая типизация

Приветствую,
может кто-нибудь стыкался с такой проблемой. Делаю апи к старому проекту для использования на android/iphone, и для них важно чтобы int отдавался как int, а не строка, float как float и тд. (не «key»:«23.2», а «key»:23.2). Это решается через JSON_NUMERIC_CHECK в json_encode, или регуляркой, если php < 5.3. Но теперь у меня проблема с тем, что если у меня в тех значениях, где должны быть чисто строки, встречается строка-число, то она тоже переводится в число. Например есть ключ title или filter, где значения должны быть строками:
— «filter»:«12 mm» остается строкой
— но «filter»:«12» -->> становится «filter»:12 хотя мне нужна здесь чисто строка

У меня решение одно, это делать постобработку уже после json_encode и через preg_replace заменять строки там где они должны быть, но кажется мне, что не очень это хорошая затея…
Вобщем может подскажете что-то? =)
Спасибо.

*Вобщем, правильный отвей ответ — следить за типами перед передачей массива в json_encode и не использовать JSON_NUMERIC_CHECK. Если данные выбраны из базы, то вручную перевести тип для необходимых ключей в числовой (intval, floatval)
  • Вопрос задан
  • 4776 просмотров
Пригласить эксперта
Ответы на вопрос 5
alekciy
@alekciy
Вёбных дел мастер
Делать нужно не ПОСТобработку, а ПРЕДобработку. Т.е. бежим по массиву и там где нам нужны цифры делаем явное приведение к нужным типам.
Ответ написан
sunsey
@sunsey Автор вопроса
Web dev
Вы знаете, попробовал кучу комбинаций, думал может проблема во вложенности и не смог повторить чтоб число кодировалось в строку…
По идее я даже понял в чем дело…

В некоторых местах я делал так

$sql = "select ...";
$result_raw = query($sql);

$api_response = array(
	"id" => $result_raw["id"],
	"filter" => $result_raw["db_filter"]
	//...
);
json_encode($api_response);


Но тут же у меня id выбрался из базы как строка…

по идее, если я вручную его приведу к инту в данном случае
$api_response = array(
	"id" => intval($result_raw["id"]),
	"filter" => $result_raw["db_filter"]
	//...
);


То все будет ок, и он отдастся нормально, и тогда не будет нужды вообще исользовать JSON_NUMERIC_CHECK и соответственно
я получу
{
	"id": 234, // instead of "id": "234"
	"filter": "12" // instead of  "filter": "12" with JSON_NUMERIC_CHECK
}

то есть то, что и нужно.

Нада опробовать на том коде, где это не работало.
Вобщем, truekenny, спасибо за наводки =)

>>А если отдавать массив json, а потом указывать тип для каждой переменной отдельно в javascript модуле?
RomanovAS, не понял Вашу мысль, конвертировать на стороне клиента в тот тип, который нужен?
Ответ написан
@Vampiro
Я бы сделал такую штуку:
ввел массив с типами переменных, которые должны быть в json явно указаны.
и применял эти типы. Как-то так, в псевдокоде.
class MyJson {
    private $types = ['id'=>intval,'name'=>'strval','price'=>'floatval'];
    public function convert2Json($array)
    {
        foreach ($array as $key=>$value)
        {
            if (isset( $this->types[$key] )) $array[$key] = {$this->types[$key]}($value);
        }
        return json_encode($array);
    }
}
Ответ написан
Комментировать
frostosx
@frostosx
А если так?

$array = array('a' => 1, 'b' => '3', 'c' => '3.14');
$json = json_encode($array);
$json = preg_replace('/\"(\d+([\.\,]\d+)?)\"/isu', '$1', $json);
Ответ написан
@kaichou
> JSON
> строгая типизация
используй XML, Люк
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы