salvob salvob - 2 years ago 56
PHP Question

Converting a string with comma separated value in a tree in PHP

I have a csv file that contains a field with a category tree in a comma separated format like this:

MotherCategory, ChildCategory1, ChildCategory2, ecc.

Some records contains only a category, other ones two, other ones three or more.

I would like to be able to store in my db all the unique categories and organise every record with a
scheme where the
value is the
of the category one level up.

At the end I should have something like:

id: 1, catname: MotherCategory, parentid: NULL
id: 2, catname: ChildCategory1, parentid: 1
id: 3, catname: ChildCategory2, parentid: 2

I've already filtered the data removing duplicates with
, next using
I am able to separate the values and I was counting the values and separating the groups basing on the length of the resultant arrays to build a tree, but I think that at the moment I am missing something to get my final result.

I've the following code. Can someone please give me a hint to solve the problem?

$cats = array_of_comma_separated_values;

foreach ($cats as $cat) {
$catarray[] = explode(",",$cat);

//first level
$level1 = array_filter ($catarray, function($item) {
if (count($item) == 1) { return true; } return false;

//second level
$level2 = array_filter ($catarray, function($item) {
if (count($item) == 2) { return true; } return false;

$level3 = array_filter ($catarray, function($item) {
if (count($item) == 3) { return true; } return false;

$level4 = array_filter ($catarray, function($item) {
if (count($item) == 4) { return true; } return false;

$level5 = array_filter ($catarray, function($item) {
if (count($item) == 5) { return true; } return false;

$level6 = array_filter ($catarray, function($item) {
if (count($item) == 6) { return true; } return false;

$level7 = array_filter ($catarray, function($item) {
if (count($item) == 7) { return true; } return false;

This gives me several arrays that i've to iterate to achieve what i'm looking for.

Now thanks to the suggestion from Kovlar I'm working on something based on

I've edited the post because maybe I was not so clear.

Answer Source

I suggest the use of array_replace_recursive() to simplify the tree-merging :)

// $tree will contain the tree at the end of the script
$tree = [];
// we treat each row of the csv one by one
foreach($csv_rows as $row) {
    // first, we split the string into an array
    $root_to_leaf = explode(',', $row['root_to_leaf']);
    // this is the "leaf" we want to append to the tree
    $leaf = [array_pop($root_to_leaf) => $row['value']];
    // we rebuild the path from the leaf to the root
    while(!empty($root_to_leaf)) {
        // add the next branching toward the root
        $leaf = [array_pop($root_to_leaf) => $leaf];
    // we append the leaf to the tree
    $tree = array_replace_recursive($tree, $leaf);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download