Я хотел бы, чтобы json_encode в PHP возвращал массив JSON, даже если индексы не в порядке

но согласно этому: http://www.php.net/manual/en/function.json-encode.php#94157 не будет.

Я использую флот, поэтому мне нужен массив с числовыми индексами, но я получаю следующее:

jsonp1282668482872 ( {"label":"Hits 2010-08-20","data":{"1281830400":34910,"1281916800":45385,"1282003200":56928,"1282089600":53884,"1282176000":50262,"1281657600":45446,"1281744000":34998}} );

так флот задыхается. Если я var_dump массива прямо перед вызовом json_encode, это будет выглядеть так:

array(7) {
  [1281830400]=>
  int(34910)
  [1281916800]=>
  int(45385)
  [1282003200]=>
  int(56928)
  [1282089600]=>
  int(53884)
  [1282176000]=>
  int(50262)
  [1281657600]=>
  int(45446)
  [1281744000]=>
  int(34998)
}

есть идеи?


person Andrew Watson    schedule 24.08.2010    source источник
comment
Связанный с этим вопрос: stackoverflow.com/questions/11195692/   -  person tres.14159    schedule 19.02.2016


Ответы (5)


Как говорит zneak, массивы Javascript (и, следовательно, JSON) не могут иметь неупорядоченные ключи массива. Таким образом, вам нужно либо смириться с тем, что вы будете работать с объектами JSON, а не с массивами, либо вызывать array_values перед json_encode:

json_encode(array_values($data));

Однако похоже, что вы хотите отобразить данные временных рядов с помощью флота. Как видно на примере временного ряда, это должен быть массив из двух элементов, например:

$.plot(
  $('#placeholder'),
  [[
    [1281830400, 34910],
    [1281916800, 45385],
    [1282003200, 56928],
    [1282089600, 53884],
    [1282176000, 50262],
    [1281657600, 45446],
    [1281744000, 34998]
  ]],
  {
    label: 'Hits 2010-08-20',
    xaxis: {mode: 'time'}
  }
)

Учитывая ваш массив (назовем его $data), мы можем получить правильный JSON следующим образом:

json_encode(
  array_map(
    function($key, $value) { return array($key, $value); },
    array_keys($data),
    array_values($data)
  )
);
person pr1001    schedule 24.08.2010
comment
Это здорово, я добился того же результата, сгенерировав JSON с помощью цикла, но ваше решение мне нравится больше. Спасибо! - person Andrew Watson; 09.09.2010
comment
Рад помочь. Пожалуйста, отметьте это как ответ, если вы считаете, что это отвечает на ваш вопрос. - person pr1001; 09.09.2010
comment
после 6 часов гугления вы решили мою проблему с получением правильного JSON, готового к графику во FLOT. СПАСИБО! - person newyuppie; 29.05.2011

Это концептуально невозможно. Вы не можете закодировать массив с фиксированными индексами в JSON.

Напоминаем, что массив JSON выглядит так:

[1, 2, 3, 4, 5]

Там нет места для размещения индексов.

Вы должны работать на стороне Javascript. Принимая, что json_encode вернет объект, вы можете преобразовать этот объект в массив. Это не должно быть слишком сложно.

function toArray(object)
{
    var result = [];
    for (var key in object)
    {
        if (!key.match(/^[0-9]+$/)) throw new Error("Key must be all numeric");
        result[parseInt(key)] = object[key];
    }
    return result;
}
person zneak    schedule 24.08.2010
comment
Я думаю, что было бы разумнее исправить размер массива в размере PHP, если бы OP контролировала его, что, похоже, они и делают. Во-первых, это должно быть немного быстрее и приведет к (едва ли) меньшему количеству данных, отправляемых клиенту. - person pr1001; 24.08.2010
comment
@ pr1001: если вы это сделаете, вы потеряете всю ключевую информацию. Поскольку ключи представляют собой временные метки, я считаю, что они важны. - person zneak; 24.08.2010
comment
Я согласен, но, как мы с pkh написали, я думаю, что он ошибся в формате массива, который ему нужен в первую очередь. - person pr1001; 24.08.2010

Вы можете заставить json_decode() создавать массивы, передав TRUE в качестве второго параметра, но вы не можете заставить json_encode() создавать массивы в первую очередь:

json_decode($json, TRUE); // force array creation
person Marc B    schedule 24.08.2010

Вы можете использовать array_merge для переиндексации массива с числовым индексом, например:

$a = array(2 => 3, 4 => 5);
$a = array_merge($a);
var_dump($a);
person Robin    schedule 24.08.2010
comment
Он потеряет ключ, а ключ кажется важным. - person zneak; 24.08.2010
comment
В этом случае ему нужен объект JSON, массив этого не сделает. - person Robin; 24.08.2010

Для флота то, что вы просите, на самом деле не то, что вы хотите. Вам нужен массив массивов, а не массив чисел. То есть вы хотите что-то похожее на это:

  [[1281830400, 34910],
   [1281916800, 45385],
   [1282003200, 56928],
   [1282089600, 53884],
   [1282176000, 50262],
   [1281657600, 45446],
   [1281744000, 34998]]

Что касается того, как это сделать в PHP, я не уверен.

person pkh    schedule 24.08.2010