<?php

$list = array(
    array("id" => 1, "parentId" => null, "text" => "Первая строка"), 
    array("id" => 2, "parentId" => 3,    "text" => "Вторая строка"), 
    array("id" => 3, "parentId" => 1,    "text" => "Третья строка"),
    array("id" => 4, "parentId" => 1,    "text" => "Четвертая строка"),
    array("id" => 5, "parentId" => null, "text" => "Пятая строка"), 
    array("id" => 6, "parentId" => 5,    "text" => "Шестая строка"), 
    ["id" => 7, "parentId" => 6, "text" => "Седьмая строка"], 
    ["id" => 8, "parentId" => 5, "text" =>  "Восьмая строка"],
);

/*
 * 1 -> 3 -> 2
 *  \
 *   -> 4
 *
 * 5 -> 6 -> 7
 *  \
 *   -> 8
 */

$roots = array_filter($list, function ($node) {
    return $node['parentId'] === null;
});

$stack = array_map(function ($root) {
    return [0, $root];
}, $roots);

function visit($depth, $node) {
    echo str_repeat('-', $depth) . $node['id'] . "\n";
}

while (count($stack)) {
    list($depth, $current) = array_shift($stack);

    visit($depth, $current);

    $currentChildren = array_filter($list, function ($node) use ($current) {
        return $node['parentId'] === $current['id'];
    });
    $depthChildMap = array_map(function ($child) use ($depth) {
        return [$depth + 1, $child];
    }, $currentChildren);

    $stack = array_merge($depthChildMap, $stack);
}
