C'est parce que vous avez toujours les catégories dans le tableau alors que vous les avez déjà affectées. Ce que vous pouvez faire est de faire la fonction où vous passez l'argument comme référence, et dans la boucle foreach pour avoir la possibilité d'effacer le tableau de cette catégorie déjà affectée. Mise en œuvre simple ci-dessous.
function getChildren(&$rows, $p = 0) {
$r = array();
foreach($rows as $row_id => $row) {
if ($row['parent_node']==$p) {
$r[$row['product_category_code']] = getChildren($rows, $row['product_category_code']);
unset($rows[$row_id]);
}
}
return $r;
}