php - Recursive data output

768
$dirs = array(
    'root_dir' => array(
        'sub_dir_1' => array(
            0 => 'file'
        ),
        'sub_dir_2' => array(
            0 => 'file'
        ),
        'sub_dir_3' => array(
            0 => 'file_1',
            1 => 'file_2',
            2 => 'file_3'
        )
    ),
);


$render = function($dirs) use (&$render) {
    echo "<ul>";
    foreach ($dirs as $parent => $children) {
        if (is_string($parent) === true) {
            echo "<li>$parent</li>";
            $render($children);
        }  else {
            echo "<li>$children</li>";           
        }
    }
    echo "</ul>";
};

$render($dirs);

Output

<ul>
    <li>root_dir</li>
    <ul>
        <li>sub_dir_1</li>
        <ul>
            <li>file</li>
        </ul>
        <li>sub_dir_2</li>
        <ul>
            <li>file</li>
        </ul>
        <li>sub_dir_3</li>
        <ul>
            <li>file_1</li>
            <li>file_2</li>
            <li>file_3</li>
        </ul>
    </ul>
</ul>

Needed output

<ul>
    <li>
        root_dir
        <ul>
            <li>
                sub_dir_1
                <ul>
                    <li>file</li>
                </ul>
            </li>
            <li>
                sub_dir_2
                <ul>
                    <li>file</li>
                </ul>
            </li>
            <li>
                sub_dir_3
                <ul>
                    <li>file_1</li>
                    <li>file_2</li>
                    <li>file_3</li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

What I am doing wrong ?

285

Answer

Solution:

        echo "<li>$parent</li>";
        $render($children);

Should be:

        echo "<li>".$parent;
        $render($children);
        echo "</li>";

Otherwise your children are outside of the parent<li>.

560

Answer

Solution:

@Niet spotted the mistake but I would go about this a slightly different way:

$render = function($dirs) use (&$render) {    
    foreach ($dirs as $parent => $children) {
        $s .= "<li>" . (is_string($parent) ? $parent . $render($children) : $children) . "</li>";       
    }
    return "<ul>$s</ul>";
};

echo $render($dirs);
  • is_string returnstrue orfalse, so no need for the=== comparison.
  • Rather thanechoing all over the place, I opted to build the string all in one go andecho it at the end. This allows the output of$render($children) to be concatenated within theforeach loop
  • You had a spare</li> in your finalecho statement - I removed it.

Hope it is of some use to you.

People are also looking for solutions to the problem: javascript - what is the difference between 'value' => 'accept', and 'checked' => TRUE, when using function form_checkbox()

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.