php object to array

131
12 сентября 2019, 01:00

Этот вопрос мусолился не раз, но все же, вот с чем столкнулся...

Вариант №1

PHP:

<?php  
$fields = [];
$fields[0] = 0;
$fields[2] = 2;
$fields[1] = 1;
$fields = (array) $fields;
die(json_encode($fields));

JS console:

{0: 0, 1: 1, 2: 2}
0: 0
1: 1
2: 2
__proto__: Object

Вариант №2

PHP:

<?php  
$fields = [];
$fields[0] = 0;
$fields[2] = 2;
$fields[1] = 1;
/// Дальше любые манипуляции с массивом
$fields = array_merge([],$fields);
///$fields = array_reverse($fields);$fields = array_reverse($fields);
///$fs = []; foreach( $fields AS $k=>$f ) $fs[$k] = $f; $fields = $fs;
///$fields = get_object_vars((object)$fields);
die(json_encode($fields));

JS console:

[0, 2, 1]
0: 0
1: 2
2: 1
length: 3
__proto__: Array(0)

1 вариант: this.fields.forEach ругается
2 вариант: порядок нарушается

Вижу только такой выход:

<?php
$fields = [];
$fields[0] = 0;
$fields[1] = NULL;
$fields[2] = 2;
$fields[1] = 1;
die(json_encode($fields));

Я одну часть массива формирую, потом в него добавляю
Предположил, прописывание индексов создаст порядок

Почему так происходит?
Какие еще варианты есть, что бы сделать массив не теряя последовательности?

Answer 1

Так происходит потому, что при сериализации массива в PHP функцией json_encode можно получить массив или объект в зависимости от того, был ли массив простым списком. Важно понимать, что значения в списке отсортированы и при обращении ко второму элементу списка вы получите второй элемент, а не элемент с индексом 2. Могучие массивы php тут требуют деликатного обращения. Если вам нужен список, то преобразуйте массив в список перед сериализацией (например с помощью функции array_values), но будьте внимательны позиция элемента в списке и его ключ не одно и то же.

Для понимания происходящего выполните (например в консоли php -a) такой код:

$arr = [];
$arr[2] = 'два';
$arr[1] = 'один';
$arr[0] = 'ноль';
$i = 0;
foreach ($arr as $k => $v) {
    echo "итерация $i - ключ $k\n";
    ++$i;
}

Кстати, в js вы можете итерировать объекты с помощью for in.

Answer 2

Предложил бы передавать из php объект вместо массива. php:

$arr = [
  '0' => 0,
  '2' => 2,
  '1' => 1,
];
echo json_encode($arr); // {"0":0,"2":2,"1":1}

Вслед за @ЕгорБанин предложу for in для итерации свойств объекта. Но это для es6.
В es5 придется немного "поплясать с бубном".

js:

var arr = JSON.parse('{"0":0,"2":2,"1":1}');
// es6
for (var item in arr) {
  console.log(item);
}
// es5
for (var idx = 0; idx < Object.keys(arr).length; idx++) {
  console.log(arr[idx]);
}
// 0
// 1 
// 2
READ ALSO
Проблема с активацией почты

Проблема с активацией почты

Написал регистрацию и активацию почты пользователей на сайтеНа почту приходит письмо с ссылкой, по который нужно перейти, чтобы активировать...

152
Убрать хешбанг (#!) с URL

Убрать хешбанг (#!) с URL

Есть сайт, нужно сделать редирект со всех его страниц на главную страницу другого сайтаЭтого я легко добился с помощью редиректа в

138
Вывод комментариев из базы данных WordPress

Вывод комментариев из базы данных WordPress

У меня есть сайт на WP, на нем есть нужная страница на которой нужно сделать вывод всех комментариев с базы данных WP,решил делать вывод из бд на php (редактор...

118
как отправить json запрос в slim&#39;е

как отправить json запрос в slim'е

Есть рабочий запрос к api:

124