Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to tranform an php array into an json string to use with JavaScript InfoVis Toolkit formart.

the objective: InfoVis Demo Tree

Json specification format: InfoVis-loading and serving JSON data

I have this php array: $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 
                    ) 

            ) 

    ) 

)           

now if I 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" 
            } 
        } 
    } 
}  

But to InfoVis the current json output (json_encode($my_array)) has 3 problems:

  1. is not using [ ]
  2. the 'children' arrays have the key names
  3. arrays items is with their key names -> example: "item_1": { ....

let me point the problem so maybe you can help with an function to transform this json string:

see this slice of json_encode($my_array) output:

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

1. problem 1:

{  
    "item_1": {  

we have to remove those keys like: "item_1":

2. problem 2:

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

the correct code for this should be:

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

"door": was removed... because it`s a key

"children": { => becomes" "children": [

An working example of 'children':

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

to clarify an complete example of WORKING Json InfoVis format:

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"
            }]
        }]
    };

is it clear to understand?

Hope anyone can help me.. I'm working on this for days!

thank you.

share|improve this question
    
What's so hard to format your array the way you need it for json_encode first? –  hakre Jan 4 '12 at 16:55
    
Hello, can you give us the PHP code used to generate your Array if it isn't too long? I think your problem come from here and not the json_encode function. You have to use numeric keys to can generate JSON Array ([]). –  Elorfin Jan 4 '12 at 17:03
    
this array is generated via this function: stackoverflow.com/questions/8676339/… @hakre that's because of InfoVis json specification see: thejit.org/static/v20/Docs/files/Loader/Loader-js.html –  Omnia Jan 4 '12 at 17:20

3 Answers 3

up vote 3 down vote accepted

Try this quickie conversion function

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);
share|improve this answer
    
Hello James! thank you so much! what a really great function! you rock!! Thank you !! –  Omnia Jan 5 '12 at 17:01

PHP doesn't differentiate between arrays (numeric keys) and associative arrays (string keys). They're all just Arrays. Javascript DOES differentiate. Since you're using string keys, they HAVE to be done as objects ({}) in JS.

You can't tell json_encode to ignore the keys in an array (e.g. your 'children' sub-arrays). That'd mean the produced JSON is NOT the same as the original PHP structure - you've now changed key names.

You'd have to process your array and convert all those children sub-array keys to numbers:

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

so that json-encode could see that it's a numerically keyed PHP array, meaning it'll produce an actual javavscript array ([]), and not an object ({}).

The alternative is writing your own JSON-encoder to do this on-the-fly for you.

share|improve this answer
    
Thank you, but how can i do this? "have to process your array and convert all those children sub-array keys to numbers" –  Omnia Jan 4 '12 at 17:22
    
Go through the array and rewrite the 'bad' parts. $new_array['child']['0'] = $bad_array['child']['grass']. –  Marc B Jan 4 '12 at 17:49

This is documented behaviour. An associative array will produce an object literal when JSON stringified with json_encode. Update your original array structure to represent the outcome you want, instead of mangling the produced JSON representation, or wrap your own solution around json_encode for each object.

Edit: attempting a cleanup operation

The code

$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);

Output

[{
    "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"
    }]
}]
share|improve this answer
    
Thank you, this array comes from stackoverflow.com/questions/8676339/… .. could you help me with this particular json_encode ? –  Omnia Jan 4 '12 at 17:24
    
@Omnia Hey, I'm not 100% I managed to achieve what you're looking for, but I think I may have done so. Take a look at my revised answer, –  nikc.org Jan 5 '12 at 9:02
1  
Hello thank you! that's @nikc-org !! great function! thank you so much! –  Omnia Jan 5 '12 at 17:00
    
@Omnia glad you like it. –  nikc.org Jan 5 '12 at 21:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.