Как должна выглядеть функция, чтоб рекурсия происходила внутри функции, а не на саму функцию.
Рекурсия - это и есть вызов функции из нее же. Вы, конечно, можете создать функцию, которая будет вызывать рекурсивную функцию, но тогда функция с рекурсией никуда не денется.
С другой стороны, любую функцию можно переписать без использования рекурсии.
Например так:
function parents($tree, $childKey) {
$parents = [];
$endOfTree = false;
$minLevel = 1;
$currentLevel = 1;
$parentBranches = [];
$branch = $tree;
$branchKey = key($branch);
$branchValue = current($branch);
while (!$endOfTree) {
// Обработка текущего элемента
if (strpos($childKey, $branchKey . ".") === 0 && $branchKey !== $childKey) {
$parents[] = (string)$branchKey;
}
// Переключение ветки на внутренни уровень, если он есть
if (is_array($branchValue) && !empty($branchValue)) {
$currentLevel++;
$parentBranches[] = $branch;
$branch = $branchValue;
$branchKey = key($branch);
$branchValue = current($branchValue);
continue;
}
// Переключение на следующий элемент
$branchValue = next($branch);
$branchKey = key($branch);
// В случае, если следующего элемента нет, возврат на уровень выше или завершение цикла
if ($branchValue === false) {
$branch = array_pop($parentBranches);
$currentLevel--;
// Возврат на уровень выше, если это возможно
if ($currentLevel >= $minLevel) {
$branchValue = next($branch);
$branchKey = key($branch);
// Завершение цикла, если уровень минимальный
} else {
$endOfTree = true;
}
}
}
// Смена направления массива и возвращение результата
return array_reverse($parents);
}
// Проверка
parents($tree, '1.3.2.2');
/*
array(3) {
[0]=>
string(5) "1.3.2"
[1]=>
string(3) "1.3"
[2]=>
string(1) "1"
}
*/