Урок 23. Як використовувати рекурcивну функцію в php?

Рекурcія (або рекурcивний виклик) – це коли функція викликає саму себе. Рекурсія досить часто використовується в php-скриптах. Але необхідно враховувати те, що дана операція використовує багато ресурсів.

Давайте розглянемо рекурсію не реальному прикладі. Припустимо у нас є сайт, в якому існує розділ «Послуги компанії». У цьому розділі в свою чергу є підрозділ «Веб-розробка» з ще одним підрозділом «Сайти-візитки». В результаті виходить ієрархічна структура, з батьківськими і дочірніми розділами. Зверніть увагу, розділ «Веб-розробка» є батьківським для підрозділу «Сайти-візитки» і дочірнім для розділу «Послуги компанії». Потрібно скласти cкрипт, який дозволить перевіряти наявність підрозділів у будь-якого розділу.

Для початку зобразимо структуру сайту в формі масиву:

<?php
$menu = array(
1 => array(
"name" => "Послуги компанії",
"parent" => 0   
),
2 => array(
"name" => "Веб-розробка",
"parent" => 1   
),
3 => array(
"name" => "Сайти-візитки",
"parent" => 2   
)
);
?>

Масив $menu складається з 3 елементів. (Ми спеціально почали нумерацію з 1, щоб 0 був вільним). Індекси елементів (1, 2 і 3) є унікальними ідентифікаторами. Кожному елементу присвоєно 2 поля:
name – назва разділу;
parent – номер батьківського розділу.

Тепер напишемо функцію, яка буде визначати, у яких розділів є підрозділи:

<?php
function has_child($arr,$page_id=0){
foreach($arr as $index => $field); {
if ($field["parent"] == $page_id) {
if ($page_id != 0){
echo $arr[$page_id]["name"]  . "має підрозділ<br>";
}
//Тут буде рекурсія!!!
has_child($arr, $index);
}
}
}
//Викликаємо функцію 1 раз
//Решта будуть виконані рекурсивно
has_child(&menu);
?>

Нагадування! Коли будете запускати цей приклад на виконання, не забудьте дописати в ньому масив $menu.

Тепер давайте покроково розглянемо виконання даної функції. При першому виклику в якості вхідних даних в функцію надходить посилання на масив $menu і кореневий елемент, той самий, вільний, з нульовим індексом, для якого за допомогою конструкції foreach шукаємо підрозділи. За допомогою рекурсії кожен знайдений нащадок перевіряється на наявність підрозділів. При цьому нам не потрібно вручну для кожного елемента викликати функцію. Вона самостійно обходить всі елементи масиву. Подібного роду перебір ієрархічного ланцюжка називається рекурсивним спуском.

При використанні рекурсії в php скриптах важливо відстежувати умови її закінчення. В іншому випадку скрипт може «зациклитися», що негативно вплине на роботу сервера.