简体   繁体   中英

Looping into a multidimensional array with PHP

I've got this array:

Array
(
    [0] => Array
        (
            [name] => System
            [order] => 1
            [icon] => stats.svg
            [0] => Array
                (
                    [title] => Multilingual
                )

            [1] => Array
                (
                    [title] => Coloring
                )

            [2] => Array
                (
                    [title] => Team work
                )

            [3] => Array
                (
                    [title] => Tutorials
                )

        )
)

I want to loop into this to show the section name and after all the features containing in the following array.

So, this is what I made:

foreach ($features as $feature => $info) {
    echo '
        '.$info['name'].'
                <ul class="menu-vertical bullets">
    ';

                foreach (array_values($info) as $i => $key) {
                    echo '
                        <li>'.$key['title'].'</li>
                    ';
                }

    echo '
                </ul>
    ';
}

It works except for the first third <li> where I have the first char of name , order and icon value.

Do you know why ?

Thanks.

In php, array_values means all the values of the array. So array_values($info) is array($info['name'], $info['order'], $info['icon'], $info[0], $info[1], $info[2], $info[3])

in your example, you can skip the non-integer keys of the $info to get your titles:

<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info[] = array('title'=>'Multilingual');
$info[] = array('title'=>'Coloring');
$features[] = $info;

foreach ($features as $feature => $info) {
    echo $info['name'] . PHP_EOL;
    echo '<ul class="menu-vertical bullets">' . PHP_EOL;
    foreach ($info as $k => $item) {
        if(!is_int($k)) continue;
        echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
    }
    echo '</ul>' . PHP_EOL;
}

BUT, your original data structure is not well designed and hard to use. For a better design, you can consider the following code, move your items to a sub array of $info :

<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info['items'] = array();
$info['items'][] = array('title'=>'Multilingual');
$info['items'][] = array('title'=>'Coloring');
$features[] = $info;

foreach ($features as $feature => $info) {
    echo $info['name'] . PHP_EOL;
    echo '<ul class="menu-vertical bullets">' . PHP_EOL;
    foreach ($info['items'] as $item) {
        echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
    }
    echo '</ul>' . PHP_EOL;
}

Sample output of the two demos:

System
<ul class="menu-vertical bullets">
<li>Multilingual</li>
<li>Coloring</li>
</ul>

It works except for the first third li where I have the first char of name, order and icon value. Do you know why ?

Why you see first chars of the values of 'name', 'order', 'icon'? Let see how PHP works.

Take the first loop as an example: foreach (array_values($info) as $i => $key)

Then $i == 0, $key == 'System'

We know that $key[0] == 'S', $key[1] == 'y', $key[2] == 's' , etc.

Then you try to access $key['title'] , but the string 'title' is not valid as a string offset, so it is converted to an integer by PHP: intval('title') == 0 .

Then $key['title'] == $key[intval('title')] == 'S'

That's what you see.

array_values return value of array so for info values is name, order, icon, 0, 1, ...

Your values foreach is wrong if you just want print title you can use:

foreach ($features as $feature => $info) {

    echo '
        '.$info['name'].'
            <ul class="menu-vertical bullets">
    ';
    //Remove some keys from info array
    $removeKeys = array('name', 'order', 'icon');
    $arr = $info;
    foreach($removeKeys as $key) {
       unset($arr[$key]);
    }

    foreach (array_values($arr) as $i => $key) {
                echo '
                    <li>'.$key['title'].'</li>
                ';
            }

    echo '
            </ul>
    ';
}

array_value() returns the values of the array, here you will get the value of the array $info and what I understand is that is not what you need. See details for array_value() .

You can check if the key for the $info is an integer. if yes, echo the title. Give this a try.

foreach ($features as $feature => $info) {
    echo $info['name'].'<ul class="menu-vertical bullets">';
    foreach ($info as $key => $value) {
        if (is_int($key)) {
            echo '<li>'.$key['title'].'</li>';  
        }
    }
    echo '</ul>';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM