phparraysforeach

How to iterate a nested array?


I need to print the below array structure as:

Node Title 1

  topic 1

  topic 2

  topic 3

  topic 4

    asset title1 

    asset title2

    asset title3

How can i do using foreach - PHP

What i have done is :

foreach($output['fields'] as $key => $value) {
        if($key == 'title') {
            echo $value;
        }
        if(count($value['main_topic'])) {
            foreach($value['main_topic'] AS $mainkey => $main_topic) {
                echo $main_topic['topic_title'];
            }
        }
    }

The above syntax is printing the title. But not the main_topic array.

Array
(
    [fields] => Array
        (
            [nid] => 136
            [node_title] => Node title 1
            [node_type] => curriculum
            [title] => Node title 1
            [main_topic] => Array
                (
                    [0] => Array
                        (
                            [row_id] => 136
                            [topic_id] => 411847
                            [weight] => 10
                            [topic_title] => topic 1
                        )

                    [1] => Array
                        (
                            [row_id] => 136
                            [topic_id] => 411839
                            [weight] => 2
                            [topic_title] => topic 2
                        )

                    [2] => Array
                        (
                            [row_id] => 136
                            [topic_id] => 411840
                            [weight] => 3
                            [topic_title] => topic 3
                        )

                    [3] => Array
                        (
                            [row_id] => 136
                            [topic_id] => 411841
                            [weight] => 4
                            [topic_title] => topic 4
                            [subfield] => Array
                                (
                                    [1] => Array
                                        (
                                            [asset_title] => asset title 1
                                        )

                                    [2] => Array
                                        (
                                            [asset_title] => asset title 2
                                        )

                                    [3] => Array
                                        (
                                            [asset_title] => asset title 3
                                        )

                                )

                        )


                )

        )

)

Solution

  • That is because you are iterating over all $output['fields']. There will never be a $value with key 'main_topic' because the key 'main_topic' is contained in the $output['fields'] array and thus exists only as $key in your foreach. The array you want is $value

    Your code should be like:

    foreach($output['fields'] as $key => $value) {
            if($key == 'title') {
                echo $value;
                continue;
            }
            if($key == 'main_topic' && is_array($value)) {
                foreach($value as $main_topic) {
                    echo $main_topic['topic_title'];
                }
            }
        }
    

    To complete this answer with a full solution (including asset titles), below is how I would write it.

    Because $output['fields'] is the starting point and to make the code more readable, I create a reference to the starting node using the =& operator so the array is not copied in memory. I do the same with the inner foreachs. Since we are not modifying data, referencing the variables is sufficient and consumes less memory and CPU:

    if (is_array($output['fields'])) {
        $node =& $output['fields'];
        echo $node['title'];
        if(is_array($node['main_topic'])) {
            foreach($node['main_topic'] as &$main) {
                echo $main['topic_title'];
                if(is_array($main['subfield'])) {
                    foreach($main['subfield'] as &$asset) {
                        echo $asset['asset_title'];
                    }
                }
            }
        } 
    }
    else {
        echo "no menu";
    }