проблема с PHP-функцией рекурсивной обработки массива

12
Dreammaker
На сайте с 20.04.2006
Offline
570
1286

Есть массив, данные в котором хранятся в формате Nested Set:

1:



array(12) {
[0]=>
array(6) {
["id"]=>
string(1) "2"
["root"]=>
string(1) "2"
["name"]=>
string(8) "New 1:24"
["level"]=>
string(1) "1"
["lft"]=>
string(1) "1"
["rgt"]=>
string(2) "24"
}
[1]=>
array(6) {
["id"]=>
string(2) "20"
["root"]=>
string(1) "2"
["name"]=>
string(11) "jkjkjk 2:15"
["level"]=>
string(1) "2"
["lft"]=>
string(1) "2"
["rgt"]=>
string(2) "15"
}
[2]=>
array(6) {
["id"]=>
string(2) "27"
["root"]=>
string(1) "2"
["name"]=>
string(15) "New Folder 3:10"
["level"]=>
string(1) "3"
["lft"]=>
string(1) "3"
["rgt"]=>
string(2) "10"
}
[3]=>
array(6) {
["id"]=>
string(2) "28"
["root"]=>
string(1) "2"
["name"]=>
string(14) "New Folder 4:5"
["level"]=>
string(1) "4"
["lft"]=>
string(1) "4"
["rgt"]=>
string(1) "5"
}
[4]=>
array(6) {
["id"]=>
string(3) "228"
["root"]=>
string(1) "2"
["name"]=>
string(22) "New Folder dvdvdsv 6:7"
["level"]=>
string(1) "4"
["lft"]=>
string(1) "6"
["rgt"]=>
string(1) "7"
}
[5]=>
array(6) {
["id"]=>
string(3) "229"
["root"]=>
string(1) "2"
["name"]=>
string(14) "fbfbdfbdfb 8:9"
["level"]=>
string(1) "4"
["lft"]=>
string(1) "8"
["rgt"]=>
string(1) "9"
}
[6]=>
array(6) {
["id"]=>
string(2) "29"
["root"]=>
string(1) "2"
["name"]=>
string(14) "45654654 11:14"
["level"]=>
string(1) "3"
["lft"]=>
string(2) "11"
["rgt"]=>
string(2) "14"
}
[7]=>
array(6) {
["id"]=>
string(3) "230"
["root"]=>
string(1) "2"
["name"]=>
string(9) "890 12:13"
["level"]=>
string(1) "4"
["lft"]=>
string(2) "12"
["rgt"]=>
string(2) "13"
}
[8]=>
array(6) {
["id"]=>
string(2) "24"
["root"]=>
string(1) "2"
["name"]=>
string(18) "New Folder 4 16:19"
["level"]=>
string(1) "2"
["lft"]=>
string(2) "16"
["rgt"]=>
string(2) "19"
}
[9]=>
array(6) {
["id"]=>
string(2) "37"
["root"]=>
string(1) "2"
["name"]=>
string(13) "9999999 17:18"
["level"]=>
string(1) "3"
["lft"]=>
string(2) "17"
["rgt"]=>
string(2) "18"
}
[10]=>
array(6) {
["id"]=>
string(3) "226"
["root"]=>
string(1) "2"
["name"]=>
string(12) "909090 20:23"
["level"]=>
string(1) "2"
["lft"]=>
string(2) "20"
["rgt"]=>
string(2) "23"
}
[11]=>
array(6) {
["id"]=>
string(3) "227"
["root"]=>
string(1) "2"
["name"]=>
string(14) "hhfghfgh 21:22"
["level"]=>
string(1) "3"
["lft"]=>
string(2) "21"
["rgt"]=>
string(2) "22"
}
}

нужно перевести в "древовидный" формат, который потом будет переводиться в JSON. Есть проблема, что затормозил на функции конвертирования, в итоге нашёл подходящую, немного её переделал - там исходный формат массива немного на другом основывался. Но есть проблема, что по первой ветке дерева функция хорошо проходит, а вот уже когда начинает идти по другим, то приписывает ребёнка на уровень выше, т.е, должно быть


1

2 3
4 5 6

А в результирующем массиве получается примерно так:


1 3

2 5 6
4

Вот реальный массив, который получается:


array(4) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(1) "2"
}
["data"]=>
string(25) "New n54y090009066690 1:18"
["state"]=>
string(4) "open"
["children"]=>
array(2) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(2) "20"
}
["data"]=>
string(10) "jkjkjk 2:9"
["state"]=>
string(4) "open"
["children"]=>
array(2) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(2) "27"
}
["data"]=>
string(14) "New Folder 3:6"
["state"]=>
string(4) "open"
["children"]=>
array(1) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(2) "28"
}
["data"]=>
string(14) "New Folder 4:5"
["state"]=>
string(4) "open"
["children"]=>
string(0) ""
}
}
}
[1]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(3) "228"
}
["data"]=>
string(18) "New Folder dvdvdsv"
["state"]=>
string(4) "open"
["children"]=>
string(0) ""
}
}
}
[1]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(3) "229"
}
["data"]=>
string(10) "fbfbdfbdfb"
["state"]=>
string(4) "open"
["children"]=>
string(0) ""
}
}
}
[1]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(2) "29"
}
["data"]=>
string(12) "45654654 7:8"
["state"]=>
string(4) "open"
["children"]=>
array(1) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(3) "230"
}
["data"]=>
string(3) "890"
["state"]=>
string(4) "open"
["children"]=>
string(0) ""
}
}
}
[2]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(2) "24"
}
["data"]=>
string(18) "New Folder 4 10:13"
["state"]=>
string(4) "open"
["children"]=>
array(1) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(2) "37"
}
["data"]=>
string(13) "9999999 11:12"
["state"]=>
string(4) "open"
["children"]=>
string(0) ""
}
}
}
[3]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(3) "226"
}
["data"]=>
string(12) "909090 14:17"
["state"]=>
string(4) "open"
["children"]=>
array(1) {
[0]=>
array(4) {
["attributes"]=>
array(1) {
["id"]=>
string(3) "227"
}
["data"]=>
string(14) "hhfghfgh 15:16"
["state"]=>
string(4) "open"
["children"]=>
string(0) ""
}
}
}
}


Вот код, на котором можно это увидеть, заодно и глянуть проблемную функцию toJSONArray:


<?php

function toJSONArray(&$cats)
{
$new = array();

while(list($id, $cat) = each($cats))
{

$new[] = array(
'attributes' => array('id'=>$cat['id']),
'data' => $cat['name'],
"state" => (isset($cat['state'])) ? "closed" : "open",
"children" => ($cat['rgt'] - $cat['lft'] != 1) ? toJSONArray($cats) : '',
);
//echo $cat['lft'] . "\n";
$next_id = key($cats);

if($next_id && ($cat['rgt'] - $cat['lft'] == 1))
{
return $new;
}
}

return $new;
}

$str = 'a:12:{i:0;a:6:{s:2:"id";s:1:"2";s:4:"root";s:1:"2";s:4:"name";s:8:"New 1:24";s:5:"level";s:1:"1";s:3:"lft";s:1:"1";s:3:"rgt";s:2:"24";}i:1;a:6:{s:2:"id";s:2:"20";s:4:"root";s:1:"2";s:4:"name";s:11:"jkjkjk 2:15";s:5:"level";s:1:"2";s:3:"lft";s:1:"2";s:3:"rgt";s:2:"15";}i:2;a:6:{s:2:"id";s:2:"27";s:4:"root";s:1:"2";s:4:"name";s:15:"New Folder 3:10";s:5:"level";s:1:"3";s:3:"lft";s:1:"3";s:3:"rgt";s:2:"10";}i:3;a:6:{s:2:"id";s:2:"28";s:4:"root";s:1:"2";s:4:"name";s:14:"New Folder 4:5";s:5:"level";s:1:"4";s:3:"lft";s:1:"4";s:3:"rgt";s:1:"5";}i:4;a:6:{s:2:"id";s:3:"228";s:4:"root";s:1:"2";s:4:"name";s:22:"New Folder dvdvdsv 6:7";s:5:"level";s:1:"4";s:3:"lft";s:1:"6";s:3:"rgt";s:1:"7";}i:5;a:6:{s:2:"id";s:3:"229";s:4:"root";s:1:"2";s:4:"name";s:14:"fbfbdfbdfb 8:9";s:5:"level";s:1:"4";s:3:"lft";s:1:"8";s:3:"rgt";s:1:"9";}i:6;a:6:{s:2:"id";s:2:"29";s:4:"root";s:1:"2";s:4:"name";s:14:"45654654 11:14";s:5:"level";s:1:"3";s:3:"lft";s:2:"11";s:3:"rgt";s:2:"14";}i:7;a:6:{s:2:"id";s:3:"230";s:4:"root";s:1:"2";s:4:"name";s:9:"890 12:13";s:5:"level";s:1:"4";s:3:"lft";s:2:"12";s:3:"rgt";s:2:"13";}i:8;a:6:{s:2:"id";s:2:"24";s:4:"root";s:1:"2";s:4:"name";s:18:"New Folder 4 16:19";s:5:"level";s:1:"2";s:3:"lft";s:2:"16";s:3:"rgt";s:2:"19";}i:9;a:6:{s:2:"id";s:2:"37";s:4:"root";s:1:"2";s:4:"name";s:13:"9999999 17:18";s:5:"level";s:1:"3";s:3:"lft";s:2:"17";s:3:"rgt";s:2:"18";}i:10;a:6:{s:2:"id";s:3:"226";s:4:"root";s:1:"2";s:4:"name";s:12:"909090 20:23";s:5:"level";s:1:"2";s:3:"lft";s:2:"20";s:3:"rgt";s:2:"23";}i:11;a:6:{s:2:"id";s:3:"227";s:4:"root";s:1:"2";s:4:"name";s:14:"hhfghfgh 21:22";s:5:"level";s:1:"3";s:3:"lft";s:2:"21";s:3:"rgt";s:2:"22";}}';

$array = unserialize($str); // для удобства массив здесь в сериализированном виде - сути это не меняет.

echo "<pre>";
var_dump($array); //массив в формате NestedSets
echo "</pre>";

$array = toJSONArray($array);

echo "<pre>";
var_dump($array); // Выходной массив для JSON
echo "</pre>";
?>

Прошу помощи, пару дней туплю.

update: Предложившему решение перечислю символические 5 вмз :)

rtyug
На сайте с 13.05.2009
Offline
263
#1

может быть вставить во временную таблицу, и из таблицы вынять (т.к. делает NESTED SET) и перевести в JSON?

rtyug добавил 29.06.2010 в 16:56

а нет, стоп, я наверное не понял, а что мешает этот массив перевести в JSON?

Спалил тему: Pokerstars вывод WMZ, etc на VISA 0% или SWIFT + Конверт USD/GBP,etc (net profit $0,5 млрд) (https://minfin.com.ua/blogs/94589307/115366/) Monobank - 50₴ на счет при рег. тут (https://clck.ru/DLX4r) | Номер SIP АТС Москва 7(495) - 0Ꝑ, 8(800) - 800Ꝑ/0Ꝑ (http://goo.gl/XOrCSn)
Dreammaker
На сайте с 20.04.2006
Offline
570
#2

rtyug, на стороне браузера используется jquery-плагин jstree (версия 0.9.9 - у них с v1+ форматы данных для JSON немного отличаются ), который для формирования дерева получает JSON.

Я хочу кешировать данные, полученные в ходе чтения всего дерева из базы, в виде массива "типа Nested Set", параллельно можно над этим массивов производить преобразования.

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

p.s. Почти всё работает уже на данный момент, кроме правильного отображения закешированного дерева. Виной - то, что формируется неправильный массив вышеуказанной функцией.

[Удален]
#3

Array
(
[attributes] => Array
(
[id] => 2
)

[data] => New 1:24
[state] => open
[children] => Array
(
[0] => Array
(
[attributes] => Array
(
[id] => 20
)

[data] => jkjkjk 2:15
[state] => open
[children] => Array
(
[0] => Array
(
[attributes] => Array
(
[id] => 27
)

[data] => New Folder 3:10
[state] => open
[children] => Array
(
[0] => Array
(
[attributes] => Array
(
[id] => 28
)

[data] => New Folder 4:5
[state] => open
)

[1] => Array
(
[attributes] => Array
(
[id] => 228
)

[data] => New Folder dvdvdsv 6:7
[state] => open
)

[2] => Array
(
[attributes] => Array
(
[id] => 229
)

[data] => fbfbdfbdfb 8:9
[state] => open
)

)

)

[1] => Array
(
[attributes] => Array
(
[id] => 29
)

[data] => 45654654 11:14
[state] => open
[children] => Array
(
[0] => Array
(
[attributes] => Array
(
[id] => 230
)

[data] => 890 12:13
[state] => open
)

)

)

)

)

[1] => Array
(
[attributes] => Array
(
[id] => 24
)

[data] => New Folder 4 16:19
[state] => open
[children] => Array
(
[0] => Array
(
[attributes] => Array
(
[id] => 37
)

[data] => 9999999 17:18
[state] => open
)

)

)

[2] => Array
(
[attributes] => Array
(
[id] => 226
)

[data] => 909090 20:23
[state] => open
[children] => Array
(
[0] => Array
(
[attributes] => Array
(
[id] => 227
)

[data] => hhfghfgh 21:22
[state] => open
)

)

)

)

)


<?
function buildJSONArray($cats, $node)
{
$row = array();
$row['attributes'] = array("id" => $node['id']);
$row['data'] = $node['name'];
$row['state'] = (isset($node['state'])) ? "closed" : "open";

if ($node['rgt'] - $node['lft'] != 1)
{
$childs = array();
foreach ($cats as $cat)
{
if ($cat['lft'] > $node['lft'] && $cat['rgt'] < $node['rgt'] && $cat['level'] - $node['level'] == 1)
{
$childs[] = buildJSONArray($cats, $cat);
}
}
$row['children'] = $childs;
}

return $row;
}

ну и юзать так


<?
$root = $array[0];
$myarray = buildJSONArray($array, $root);

я так понимаю - правильно :)

bearman добавил 29.06.2010 в 17:23

данные не проверял даже, мельком глянул, так что проверьте :)

ну и номер телефона - Z214962204619 :D

Dreammaker
На сайте с 20.04.2006
Offline
570
#4
bearman:
данные не проверял даже, мельком глянул, так что проверьте

спасибо, сейчас за займусь. По результатам - отпишусь и/или "отзвонюсь по телефону" :)

Dreammaker добавил 29.06.2010 в 18:04

Благодарность ушла по адресу.

Теперь я выяснил, что проблема была не только в этой функции :D

И странное совпадение я сегодня уже перечислял средства на кошелёк, который оканчивается на 619 о_О

Dreammaker
На сайте с 20.04.2006
Offline
570
#5

update: Спасибо огромное ещё раз :) всё-таки проблема только в ней была, просто прошлый раз видно старый кеш не почистил, и поэтому дерево старое отобразилось. Сейчас глянул всё показывается как нужно (ну разве что вёрстка дерева хромает немного, но это уже к делу не относится :) ):

jpg image.jpg
[Удален]
#6

Dreammaker, мы - молодцы!)

bearman добавил 29.06.2010 в 18:19

Dreammaker:
который оканчивается на 619 о_О

интересно, что у меня не выскочила авторизация вашего аккаунта оО ))) мат операции между нами уже были чтоли? я не помню)

можт вм глючит конечно

Dreammaker
На сайте с 20.04.2006
Offline
570
#7

bearman, нет, там другой кошель, другого человека. Именно, что совпадение, что оба заканчиваются на 619 (ну и начинаются на 2, но это уже менее странно :) ).

[Удален]
#8

Dreammaker, да пофигу) не суть :)

Dreammaker
На сайте с 20.04.2006
Offline
570
#9

bearman, да, главное что результат достигнут. :)

[Удален]
#10

Извините, не особо вникал в тему, но надо было бы сначала сказать, чем не подходит json_encode


$ php -a
Interactive shell

php > $a = array('uno'=>1,'dos'=>'2','tres'=>3);
php > var_export(json_encode($a));
'{"uno":1,"dos":"2","tres":3}'

И небольшое пожаление - массивы выкладывать при помощи var_export, а не var_dump, чтобы можно было скопировать.

А вот и ваш пример


php > $str = 'a:12:{i:0;a:6:{s:2:"id";s:1:"2";s:4:"root";s:1:"2";s:4:"name";s:8:"New 1:24";s:5:"level";s:1:"1";s:3:"lft";s:1:"1";s:3:"rgt";s:2:"24";}i:1;a:6:{s:2:"id";s:2:"20";s:4:"root";s:1:"2";s:4:"name";s:11:"jkjkjk 2:15";s:5:"level";s:1:"2";s:3:"lft";s:1:"2";s:3:"rgt";s:2:"15";}i:2;a:6:{s:2:"id";s:2:"27";s:4:"root";s:1:"2";s:4:"name";s:15:"New Folder 3:10";s:5:"level";s:1:"3";s:3:"lft";s:1:"3";s:3:"rgt";s:2:"10";}i:3;a:6:{s:2:"id";s:2:"28";s:4:"root";s:1:"2";s:4:"name";s:14:"New Folder 4:5";s:5:"level";s:1:"4";s:3:"lft";s:1:"4";s:3:"rgt";s:1:"5";}i:4;a:6:{s:2:"id";s:3:"228";s:4:"root";s:1:"2";s:4:"name";s:22:"New Folder dvdvdsv 6:7";s:5:"level";s:1:"4";s:3:"lft";s:1:"6";s:3:"rgt";s:1:"7";}i:5;a:6:{s:2:"id";s:3:"229";s:4:"root";s:1:"2";s:4:"name";s:14:"fbfbdfbdfb 8:9";s:5:"level";s:1:"4";s:3:"lft";s:1:"8";s:3:"rgt";s:1:"9";}i:6;a:6:{s:2:"id";s:2:"29";s:4:"root";s:1:"2";s:4:"name";s:14:"45654654 11:14";s:5:"level";s:1:"3";s:3:"lft";s:2:"11";s:3:"rgt";s:2:"14";}i:7;a:6:{s:2:"id";s:3:"230";s:4:"root";s:1:"2";s:4:"name";s:9:"890 12:13";s:5:"level";s:1:"4";s:3:"lft";s:2:"12";s:3:"rgt";s:2:"13";}i:8;a:6:{s:2:"id";s:2:"24";s:4:"root";s:1:"2";s:4:"name";s:18:"New Folder 4 16:19";s:5:"level";s:1:"2";s:3:"lft";s:2:"16";s:3:"rgt";s:2:"19";}i:9;a:6:{s:2:"id";s:2:"37";s:4:"root";s:1:"2";s:4:"name";s:13:"9999999 17:18";s:5:"level";s:1:"3";s:3:"lft";s:2:"17";s:3:"rgt";s:2:"18";}i:10;a:6:{s:2:"id";s:3:"226";s:4:"root";s:1:"2";s:4:"name";s:12:"909090 20:23";s:5:"level";s:1:"2";s:3:"lft";s:2:"20";s:3:"rgt";s:2:"23";}i:11;a:6:{s:2:"id";s:3:"227";s:4:"root";s:1:"2";s:4:"name";s:14:"hhfghfgh 21:22";s:5:"level";s:1:"3";s:3:"lft";s:2:"21";s:3:"rgt";s:2:"22";}}';
php > $a = unserialize($str);
php > var_Export(json_encode($a));
'[{"id":"2","root":"2","name":"New 1:24","level":"1","lft":"1","rgt":"24"},{"id":"20","root":"2","name":"jkjkjk 2:15","level":"2","lft":"2","rgt":"15"},{"id":"27","root":"2","name":"New Folder 3:10","level":"3","lft":"3","rgt":"10"},{"id":"28","root":"2","name":"New Folder 4:5","level":"4","lft":"4","rgt":"5"},{"id":"228","root":"2","name":"New Folder dvdvdsv 6:7","level":"4","lft":"6","rgt":"7"},{"id":"229","root":"2","name":"fbfbdfbdfb 8:9","level":"4","lft":"8","rgt":"9"},{"id":"29","root":"2","name":"45654654 11:14","level":"3","lft":"11","rgt":"14"},{"id":"230","root":"2","name":"890 12:13","level":"4","lft":"12","rgt":"13"},{"id":"24","root":"2","name":"New Folder 4 16:19","level":"2","lft":"16","rgt":"19"},{"id":"37","root":"2","name":"9999999 17:18","level":"3","lft":"17","rgt":"18"},{"id":"226","root":"2","name":"909090 20:23","level":"2","lft":"20","rgt":"23"},{"id":"227","root":"2","name":"hhfghfgh 21:22","level":"3","lft":"21","rgt":"22"}]'
php >
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий