PHP масив към Json дървовиден формат

Искам да трансформирам php масив в json низ, който да използвам с формата на JavaScript InfoVis Toolkit.

целта: InfoVis Demo Tree

Json спецификационен формат: InfoVis-зареждане и обслужване на JSON данни

Имам този php масив: $my_array:

Array 
( 
    [item_1] => Array 
        ( 
            [id] => item_1_ID 
            [name] => item_1_NAME 
            [data] => item_1_DATA 
            [children] => Array 
                ( 
                    [door] => Array 
                        ( 
                            [id] => door_ID 
                            [name] => door_NAME 
                            [data] => door_DATA 
                            [children] => Array 
                            ( 
                                [mozart] => Array 
                                    ( 
                                        [id] => mozart_ID 
                                        [name] => mozart_NAME 
                                        [data] => mozart_DATA 
                                        [children] => Array 
                                            ( 
                                                [grass] => Array 
                                                    ( 
                                                        [id] => grass_ID 
                                                        [name] => grass_NAME 
                                                        [data] => yes 
                                                    ) 

                                                [green] => Array 
                                                    ( 
                                                        [id] => green_ID 
                                                        [name] => green_NAME 
                                                        [data] => no 
                                                    ) 

                                                [human] => Array 
                                                    ( 
                                                        [id] => human_ID 
                                                        [name] => human_NAME 
                                                        [data] => human_DATA 
                                                        [children] => Array 
                                                            ( 
                                                                [blue] => Array 
                                                                    ( 
                                                                        [id] => blue_ID 
                                                                        [name] => blue_NAME 
                                                                        [data] => blue_DATA 
                                                                        [children] => Array 
                                                                            ( 
                                                                                [movie] => Array 
                                                                                    ( 
                                                                                        [id] => movie_ID 
                                                                                        [name] => movie_NAME 
                                                                                        [data] => yes 
                                                                                    ) 

                                                                            ) 

                                                                    ) 

                                                            ) 

                                                    ) 

                                            ) 

                                    ) 

                            ) 

                    ) 

                [beat] => Array 
                    ( 
                        [id] => beat_ID 
                        [name] => beat_NAME 
                        [data] => yes 
                    ) 

                [music] => Array 
                    ( 
                        [id] => music_ID 
                        [name] => music_NAME 
                        [data] => no 
                    ) 

            ) 

    ) 

)           

сега, ако json_encode($my_array);

{ 
    "item_1": { 
        "id": "item_1_ID", 
        "name": "item_1_NAME", 
        "data": "item_1_DATA", 
        "children": { 
            "door": { 
                "id": "door_ID", 
                "name": "door_NAME", 
                "data": "door_DATA", 
                "children": { 
                    "mozart": { 
                        "id": "mozart_ID", 
                        "name": "mozart_NAME", 
                        "data": "mozart_DATA", 
                        "children": { 
                            "grass": { 
                                "id": "grass_ID", 
                                "name": "grass_NAME", 
                                "data": "yes" 
                            }, 
                            "green": { 
                                "id": "green_ID", 
                                "name": "green_NAME", 
                                "data": "no" 
                            }, 
                            "human": { 
                                "id": "human_ID", 
                                "name": "human_NAME", 
                                "data": "human_DATA", 
                                "children": { 
                                    "blue": { 
                                        "id": "blue_ID", 
                                        "name": "blue_NAME", 
                                        "data": "blue_DATA", 
                                        "children": { 
                                            "movie": { 
                                                "id": "movie_ID", 
                                                "name": "movie_NAME", 
                                                "data": "yes" 
                                            } 
                                        } 
                                    } 
                                } 
                            } 
                        } 
                    } 
                } 
            }, 
            "beat": { 
                "id": "beat_ID", 
                "name": "beat_NAME", 
                "data": "yes" 
            }, 
            "music": { 
                "id": "music_ID", 
                "name": "music_NAME", 
                "data": "no" 
            } 
        } 
    } 
}  

Но за InfoVis текущият json изход (json_encode($my_array)) има 3 проблема:

  1. не използва []
  2. масивите 'дете' имат имената на ключовете
  3. масиви елементи е с техните имена на ключове -> пример: "item_1": { ....

позволете ми да посоча проблема, така че може би можете да помогнете с функция за трансформиране на този json низ:

вижте този фрагмент от json_encode($my_array) изход:

{  
    "item_1": {  
        "id": "item_1_ID",  
        "name": "item_1_NAME",  
        "data": "item_1_DATA",  
        "children": {  
            "door": {  
                "id": "door_ID",  

1. проблем 1:

{  
    "item_1": {  

трябва да премахнем тези ключове като: "item_1":

2. проблем 2:

"children": {  
            "door": {  
                "id": "door_ID",  

правилният код за това трябва да бъде:

"children": [  
            {  
                "id": "door_ID",......  

"врата": беше премахната... защото е ключ

"деца": { => става" "деца": [

Работещ пример за „деца“:

"children": [  
    {  
        "id": "grass_ID",  
        "name": "grass_NAME",  
        "data": "yes"  
    },  
    {  
        "id": "green_ID",  
        "name": "green_NAME",  
        "data": "no"  
    }  
]  

за изясняване на пълен пример за РАБОТЕЩ Json InfoVis формат:

json = {
        id: "node02",
        name: "0.2",
        children: [{
            id: "node13",
            name: "1.3",
            children: [{
                id: "node24",
                name: "2.4"
              }, {
                id: "node222",
                name: "2.22"
              }]
        }, {
            id: "node125",
            name: "1.25",
            children: [{
                id: "node226",
                name: "2.26"
            }, {
                id: "node237",
                name: "2.37"
            }, {
                id: "node258",
                name: "2.58"
            }]
        }, {
            id: "node165",
            name: "1.65",
            children: [{
                id: "node266",
                name: "2.66"
            }, {
                id: "node283",
                name: "2.83"
            }, {
                id: "node2104",
                name: "2.104"
            }, {
                id: "node2109",
                name: "2.109"
            }, {
                id: "node2125",
                name: "2.125"
            }]
        }, {
            id: "node1130",
            name: "1.130",
            children: [{
                id: "node2131",
                name: "2.131"
            }, {
                id: "node2138",
                name: "2.138"
            }]
        }]
    };

ясно ли е да се разбере?

Надявам се, че някой може да ми помогне.. Работя върху това от дни!

Благодаря ти.


person Omnia    schedule 04.01.2012    source източник
comment
Какво е толкова трудно първо да форматирате своя масив по начина, по който ви трябва за json_encode?   -  person hakre    schedule 04.01.2012
comment
Здравейте, можете ли да ни дадете PHP кода, използван за генериране на вашия масив, ако не е твърде дълъг? Мисля, че проблемът ви идва от тук, а не от функцията json_encode. Трябва да използвате цифрови клавиши, за да генерирате JSON масив ([]).   -  person Elorfin    schedule 04.01.2012
comment
този масив се генерира чрез тази функция: stackoverflow. com/questions/8676339/ @hakre това е заради спецификацията на InfoVis json вижте: thejit.org/static/v20/Docs/files/Loader/Loader-js.html   -  person Omnia    schedule 04.01.2012


Отговори (3)


Опитайте тази функция за бързо преобразуване

function fixit($yourArray) {
    $myArray = array();
    foreach ($yourArray as $itemKey => $itemObj) {
        $item = array();
        foreach ($itemObj as $key => $value) {
            if (strtolower($key) == 'children') {
                $item[$key] = fixit($value);
            } else {
                $item[$key] = $value;
            }
        }
        $myArray[] = $item;
    }
    return $myArray;
}

$fixed = fixit($my_array);
$json = json_encode($fixed);
person James    schedule 04.01.2012
comment
Здравей Джеймс! много благодаря! каква наистина страхотна функция! супер си!! Благодаря ти !! - person Omnia; 05.01.2012

PHP не прави разлика между масиви (цифрови ключове) и асоциативни масиви (низови ключове). Всички те са просто масиви. Javascript прави разлика. Тъй като използвате низови ключове, те ТРЯБВА да бъдат направени като обекти ({}) в JS.

Не можете да кажете на json_encode да игнорира ключовете в масив (напр. вашите „деца“ подмасиви). Това би означавало, че произведеният JSON НЕ е същият като оригиналната PHP структура - сега сте променили имената на ключовете.

Ще трябва да обработите своя масив и да преобразувате всички тези ключове на подмасив от деца в числа:

grass -> 0
green -> 1
etc...

така че json-encode да може да види, че това е PHP масив с цифров ключ, което означава, че ще произведе действителен javavscript масив ([]), а не обект ({}).

Алтернативата е да напишете свой собствен JSON-енкодер, който да прави това в движение вместо вас.

person Marc B    schedule 04.01.2012
comment
Благодаря ви, но как мога да направя това? трябва да обработят вашия масив и да преобразуват всички тези ключове на подмасиви на деца в числа - person Omnia; 04.01.2012
comment
Преминете през масива и пренапишете „лошите“ части. $new_array['child']['0'] = $bad_array['child']['grass']. - person Marc B; 04.01.2012

Това е документирано поведение. Асоциативен масив ще произведе обектен литерал, когато JSON е стрингован с json_encode. Актуализирайте структурата на оригиналния си масив, за да представи желания резултат, вместо да разваляте създаденото JSON представяне, или обвийте собственото си решение около json_encode за всеки обект.

Редактиране: опит за операция за почистване

Кодът

$original = <your original data-array>; // assumed, I reversed your encoded JSON as test data

// Start by stripping out the associative keys for level 1
$clean = array_values($original);

// Then recursively descend array, and do the same for every children-property encountered
function &recursiveChildKeysCleaner(&$arr) {
    // If $arr contains 'children'...
    if (array_key_exists('children', $arr)) {
        /// ...strip out associative keys
        $arr['children'] = array_values($arr['children']);

        // ...and descend each child
        foreach ($arr['children'] as &$child) {
            recursiveChildKeysCleaner($child);
        }
    }

    return $arr;
}

foreach ($clean as &$item) {
    recursiveChildKeysCleaner($item);
}
unset($item);
echo json_encode($clean);

Изход

[{
    "id": "item_1_ID",
    "name": "item_1_NAME",
    "data": "item_1_DATA",
    "children": [{
        "id": "door_ID",
        "name": "door_NAME",
        "data": "door_DATA",
        "children": [{
            "id": "mozart_ID",
            "name": "mozart_NAME",
            "data": "mozart_DATA",
            "children": [{
                "id": "grass_ID",
                "name": "grass_NAME",
                "data": "yes"
            },
            {
                "id": "green_ID",
                "name": "green_NAME",
                "data": "no"
            },
            {
                "id": "human_ID",
                "name": "human_NAME",
                "data": "human_DATA",
                "children": [{
                    "id": "blue_ID",
                    "name": "blue_NAME",
                    "data": "blue_DATA",
                    "children": [{
                        "id": "movie_ID",
                        "name": "movie_NAME",
                        "data": "yes"
                    }]
                }]
            }]
        }]
    },
    {
        "id": "beat_ID",
        "name": "beat_NAME",
        "data": "yes"
    },
    {
        "id": "music_ID",
        "name": "music_NAME",
        "data": "no"
    }]
}]
person nikc.org    schedule 04.01.2012
comment
Благодаря ви, този масив идва от stackoverflow.com /questions/8676339/ .. можете ли да ми помогнете с този конкретен json_encode? - person Omnia; 04.01.2012
comment
@Omnia Хей, не съм 100% успях да постигна това, което търсиш, но мисля, че може да съм го направил. Разгледайте преработения ми отговор, - person nikc.org; 05.01.2012
comment
Здравейте благодаря! това е @nikc-org !! страхотна функция! много благодаря! - person Omnia; 05.01.2012