fork download
  1. <?php
  2.  
  3. $text = <<<'EOD'
  4. Категория1
  5.   Подкатегория1
  6.   Подкатегория2
  7.   ПодПодкатегория1
  8.   ПодПодкатегория2
  9.   ПодПодПодкатегория1
  10.   Подкатегория3
  11. Категория2
  12.   Подкатегория4
  13. EOD;
  14.  
  15. // нормализуем форматирование
  16. $text = str_replace(' ', "\t", $text);
  17.  
  18. function buildTree(array &$lines, $level = 0) {
  19. $nodes = [];
  20. $currentLevel = $level;
  21. while (count($lines)) {
  22. // подбираем первую строку
  23. $line = $lines[0];
  24. $currentLevel = strlen(preg_split("/^(\t*)/", $line, 2, PREG_SPLIT_DELIM_CAPTURE)[1]);
  25. if ($currentLevel - $level > 1) {
  26. throw new \InvalidArgumentException("Wrong formatting!");
  27. }
  28.  
  29. $node = [];
  30. if ($currentLevel > $level) {
  31. $node['children'] = buildTree($lines, $level+1);
  32. } else if ($currentLevel < $level) {
  33. return $nodes;
  34. }
  35. $node['name'] = ltrim($line, "\t");
  36. $nodes[] = $node;
  37. array_shift($lines);
  38. }
  39.  
  40. return $nodes;
  41. }
  42.  
  43. var_dump(buildTree(explode("\n", $text)));
Success #stdin #stdout 0.01s 20520KB
stdin
Standard input is empty
stdout
array(2) {
  [0]=>
  array(1) {
    ["name"]=>
    string(19) "Категория1"
  }
  [1]=>
  array(2) {
    ["children"]=>
    array(4) {
      [0]=>
      array(1) {
        ["name"]=>
        string(25) "Подкатегория1"
      }
      [1]=>
      array(1) {
        ["name"]=>
        string(25) "Подкатегория2"
      }
      [2]=>
      array(2) {
        ["children"]=>
        array(3) {
          [0]=>
          array(1) {
            ["name"]=>
            string(31) "ПодПодкатегория1"
          }
          [1]=>
          array(1) {
            ["name"]=>
            string(31) "ПодПодкатегория2"
          }
          [2]=>
          array(2) {
            ["children"]=>
            array(1) {
              [0]=>
              array(1) {
                ["name"]=>
                string(37) "ПодПодПодкатегория1"
              }
            }
            ["name"]=>
            string(37) "ПодПодПодкатегория1"
          }
        }
        ["name"]=>
        string(31) "ПодПодкатегория1"
      }
      [3]=>
      array(1) {
        ["name"]=>
        string(25) "Подкатегория4"
      }
    }
    ["name"]=>
    string(25) "Подкатегория1"
  }
}