Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nolros's avatar
Level 23

Anyone use franzose/ClosureTable - any good or other ?

I tried using a number of Nested Sets, but it a performance hog. Anyone using this or any other closure tables. I'm have a 4 level depth folder type structure.

Thanks to Jarek for pointing me in this direction.

Cheers

0 likes
4 replies
otepas's avatar

I just started using it, but I haven't done thorough tests to check the performance. So far so good.

1 like
JarekTkaczyk's avatar
Level 53

Performance-wise it will be better than nested sets for sure. I haven't used the package enough to give feedback, but I suppose it's good. Anyway you can pretty easily do it yourself if you like.

Have a look at this example of how to build a tree from the collection https://laracasts.com/discuss/channels/general-discussion/eloquent-infinite-children-into-usable-array-and-render-it-to-nested-ul/replies/34455

It's trivial with closure table to build a tree (or subtree):

$someId; // id of the directory you want subtree for

// get the Tree collection - check linked post
$descendants = Directory::join('directory_closure as c', 'c.ancestor_id', '=', 'directories.id')
    ->where('c.ancestor_id', $someId)
    ->select('directories.*')
    ->get();

// build nested tree structure
$subTree = $descendants->buildTree();

Saving new entries is just a little bit harder, but pretty much as fast as simple inserts - that's huge advantage compared to nested set pattern.

1 like
nolros's avatar
Level 23

@JarekTkaczyk been playing around it with today. Works great and like yous aid so much better than nested sets as it allows for a fair amount of plain RAW and Eloquent manipulation, but because of the simple parent, ancestor and descendant approach makes it a hundred times faster than nested stes ... thanks a million

btw, this is what I use to build the tree

    function buildTree(array &$elements, $parentId = 0) 
    {
        $branch = array();

        foreach ($elements as $element)
        {
            if ($element['parent'] == $parentId) 
            {
                $children = self::buildTree($elements, $element['id']);
                if ($children) 
                {
                    $element['children'] = $children;
                }
                
                $branch[$element['id']] = $element;
                
                unset($elements[$element['id']]);
                
            }
        }
        return $branch;
        
    }
1 like
romanberdnikov's avatar

@nolros More universal way is to select elements by key, and also now it should be 'parent_id'

	public static function buildTree( array &$elements, $parentId = 0 ) {
		$tree = array();

		foreach ( $elements as $k => $element ) {
			if ( $element['parent_id'] == $parentId ) {

				$children = self::buildTree( $elements, $element['id'] );
				if ( $children ) {
					$element['children'] = $children;
				}

				$tree[$element['id']] = $element;

				unset($elements[$k]);
			}
		}

		return $tree;
	}

Please or to participate in this conversation.