Искам да уча PHP и да правя сайтове сам

От: Искам да уча PHP и да правя сайтове сам

Някой може ли да ми обясни защо не работи по-долния код за рекурсия. Опитвам се да я разбера тая рекурсия и искам сам да си правя рекурсивни менюта за страниците, но пусто да опустее, не мога да схвана къде ми е грешката :(
PHP:
<?php
// МАСИВ ($id, $parend_id, $title)
$arr = array(
	array(1, 0, "edno"),
	array(2, 0, "dve"),
	array(3, 1, "edno-edno"),
	array(4, 3, "edno-edno-edno"),
	array(5, 1, "edno-dve"),
	array(6, 2, "dve-edno")
);


function recurse($arr, $pid, $out){

	foreach ($arr as $ar){
		if($ar[1]==$pid){
			$out .= "  ".$ar[2]."\n";
			$child = recurse($arr, $ar[0], $out);
		}
	}
if($out) return $out;
else return false;
}

print recurse($arr, 0, $out="");
А си помислих по едно време, че съм започнал да схващам нещата :).
ХЕЛП!
 
От: Искам да уча PHP и да правя сайтове сам

К'во точно се опитваш да постигнеш с тая функция?
 
От: Искам да уча PHP и да правя сайтове сам

Искам да изкарам подред главна секция и подсекциите към нея. Т.е. да получа някаква дървовидна структура от сорта:

edno
_edno-edno
__edno-edno-edno
_edno-dve
dve
_dve-edno

Но преди всичко искам да разбера как работи рекурсията, щото това чудо ми е познато само на теория.
 
От: Искам да уча PHP и да правя сайтове сам

Нещо не мога да разбера масива ти. Каква е логиката ти за главна и подсекция?

Рекурсията е когато функцията ползва извиква себе си в конструкцията си.
 
От: От: Искам да уча PHP и да правя сайтове сам

Нещо не мога да разбера масива ти. Каква е логиката ти за главна и подсекция?

Рекурсията е когато функцията ползва извиква себе си в конструкцията си.
Показал съм с коментар каква е идеята на масива:
// МАСИВ ($id, $parend_id, $title)
Всеки елемент има parent-елемент (родителски). Главното ниво е с parent 0.
Викам фукцията в конструкцията и:
$child = recurse($arr, $ar[0], $out);
Обаче първо не ми вади всички дъщерни елементи. По скоро ги вади и после някъде зачезват - това го видях дебъгера на Zend Studio.
Второ - не ги форматира с шпация отстояние.
Въпроса ми е как да обходя този прост масив с 3 слоя на дълбочина. Сигурен съм, че за един програмист това е елементарно. Но аз с новобранския ми опит все още не съм го разгадал.
 
От: От: Искам да уча PHP и да правя сайтове сам

Искам да изкарам подред главна секция и подсекциите към нея. Т.е. да получа някаква дървовидна структура от сорта:

edno
_edno-edno
__edno-edno-edno
_edno-dve
dve
_dve-edno

Но преди всичко искам да разбера как работи рекурсията, щото това чудо ми е познато само на теория.

Защо не попиташ твоя приятел, който ти е казал че можеш да научиш какъвто и да е програмен език за 24 часа?

П.С. Примерно решение от мен с проблемната рекурсия:

PHP:
// МАСИВ ($id, $parend_id, $title) 
$arr = array( 
    array(1, 0, "edno"), 
    array(2, 0, "dve"), 
    array(3, 1, "edno-edno"), 
    array(4, 3, "edno-edno-edno"), 
    array(5, 1, "edno-dve"), 
    array(6, 2, "dve-edno") 
); 


function recurse($arr, $pid, $space = ''){ 
	
	$output = '';
    
	foreach ($arr as $ar) { 

        if($ar[1] == $pid) { 
			
			$output .=  $space . $ar[2] . "\n";
			
			if ($children = recurse($arr, $ar[0], $space . '_')) {
				$output .= $children; 
			} 
		}
    }
	
    return $output;
	
} 

echo '<pre>' . recurse($arr, 0, '') . '</pre>';
 
От: Искам да уча PHP и да правя сайтове сам

@stan_bg, много благодаря!
Не го разбрах напълно, щото ми е трудно да мисля в такава дълбочина. Но като го изтествам в дебъгера, мисля, че ще схвана логиката. Може би трябва да мисля от зад напред. От слоя, който е най-ниско към най-високия.
 
От: Искам да уча PHP и да правя сайтове сам

Още от тук ти започва проблема :)
PHP:
<?php 
// МАСИВ ($id, $parend_id, $title) 
$arr = array( 
    array(1, 0, "edno"), 
    array(2, 0, "dve"), 
    array(3, 1, "edno-edno"), 
    array(4, 3, "edno-edno-edno"), 
    array(5, 1, "edno-dve"), 
    array(6, 2, "dve-edno") 
);

пусни един print_r на двете и си помисли, кое ти изглежда по интуитивно и логично :D
PHP:
<?php 
$arr = array( 
    "edno" => array("edno-edno", "edno-dve"), 
    "dve" => array("dve-edno", "dve-dve") ), 

);
 
От: Искам да уча PHP и да правя сайтове сам

Още от тук ти започва проблема :)

Всъщност този модел на представяне на йерархично структурирана информация е доста често срещан и популярен - The Adjacency List Model.
 
От: Искам да уча PHP и да правя сайтове сам

@stan_bg, ти си гений! Благодаря ти и за правилната терминология ("The Adjacency List Model") на подобно дървовидно обхождане! Това няма кой да ми го каже, а вече като го знам си намерих много уроци от където да чета. Златен си, човече!
Започнах да схващам каква е идеята. Най-трудно ми беше да схвана защо в началото се нулира (всъщност се декларира) $output. Объркването ми идваше от това, че си мислех, че при всяко обхождане стария резултат трябва да се запази и фунлцията да се стартира наново. А то всъщност основна функция се стартира само веднъж. САМО ВЕДНЪЖ, по дяволите! Всяко следващо стартиране в дълбочина е дъщерно на основната функция. Да го web-a, голяма идея има в тая рекурсия.

Сега се чудя, дали не мога да оптимизирам времето и да съкратя броя на проверките. Примерно, ако разкарам всеки обходен елемент с unset()? Най-добре да го пробвам...
PHP:
<?php
$arr = array(
    array(1, 0, "edno"),
    array(2, 0, "dve"),
    array(3, 1, "edno-edno"),
    array(4, 3, "edno-edno-edno"),
    array(5, 1, "edno-dve"),
    array(6, 2, "dve-edno"),
    array(6, 1, "edno-tri")
);


function recurse($arr, $pid, $space = ''){ 
    $output = '';

    foreach ($arr as $key=>$ar) { 

        if($ar[1] == $pid) { 

            $output .=  $space . $ar[2] . "\n";
            $pid_temp = $ar[0];
            unset($arr[$key]);

            if ($children = recurse($arr, $pid_temp, $space . '_')) {
                $output .= $children; 
            }
        }
    }

    return $output;
}

echo recurse($arr, 0, '');
И СЕ ПОЛУЧИ!!! Yes!!!!! :) Голям кеф е!
Сега няма нужда да обхожда елементи, които вече е прекарало.
 
От: Искам да уча PHP и да правя сайтове сам

И на мен не ми харесва тоя модел, но пък това дето си се сетил за unset() е напредничаво за новобранец, значи има хляб в тебе :) Или просто имаш някакви навици от C++, който език е пълен ад за мене :mrgreen:
 
От: От: Искам да уча PHP и да правя сайтове сам

Или просто имаш някакви навици от C++, който език е пълен ад за мене :mrgreen:
Това е език, който учи на дисциплина. Писал ли на него нямаш ядове с нищо друго :roll:
 
От: Искам да уча PHP и да правя сайтове сам

Модела го видях, че се използва в доста. Използват го за създаване на йерархична структура в онлайн магазини, където се разделят продуктите на склад, секция, подсекция. Използват го много и при създаване на дървовидни менюта и падащи менюта. И изобщо за всичко, дето е под формата на каталог с дъщерни секции.

Има ли други модели за изграждане на дървовидни бази данни?
 
От: От: От: Искам да уча PHP и да правя сайтове сам

Това е език, който учи на дисциплина. Писал ли на него нямаш ядове с нищо друго :roll:
Да, C++ и на мен ми помогна много, за да започна да уча PHP. Аз и в C/C++ не бях стигнал кой знае до къде, но явно нещо ми е останало в главата, защото намирам доста препратки. Хубавото на PHP e, че има много хубава документация и не е толкова педантичен от към синтаксиса и променливите.
В C++ като стигнах до обектите и се отказах. Но мисля, че в PHP ще успея да ги разбера.
 
От: От: От: Искам да уча PHP и да правя сайтове сам

Това е език, който учи на дисциплина. Писал ли на него нямаш ядове с нищо друго :roll:

Мани, мани... мъчих се да направя едно .dll, което е NPAPI плъгин за браузърите. После се мъчих да направя друг .dll за TCP/IP комуникация. Мъка голяма, нямам думи, постоянно ми показва грешки докато се опитвам да нацеля как да работя със стрингове. Преди време без много познания чатнах PHP за около месец, сега не мога да чатна C++ и за повече време + опит в програмирането на разни други езици :lol:
 
От: Искам да уча PHP и да правя сайтове сам

Модела го видях, че се използва в доста. Използват го за създаване на йерархична структура в онлайн магазини, където се разделят продуктите на склад, секция, подсекция. Използват го много и при създаване на дървовидни менюта и падащи менюта. И изобщо за всичко, дето е под формата на каталог с дъщерни секции.

Има ли други модели за изграждане на дървовидни бази данни?

Не съм пробвал тия неща, само знам че има дървовидни бази данни сред NoSQL, по-конкретно Neo4j.
 
От: Искам да уча PHP и да правя сайтове сам

@Fix - щом искаш да научиш PHP ще ти споделя, че за нашия PHP курс има 4 свободни места за момента. Добре дошъл си! :)
 
От: Искам да уча PHP и да правя сайтове сам

Макар че вече си се справил явно, може да разгледаш:
Graph representation
Graph traversing

Това е на практика същото, което правиш, макар че е по-опростено, защото имаш дърво и няма да се натъкнеш на цикъл. Погледни http://bg.wikipedia.org/wiki/Обхождане_в_дълбочина

Може да ти е полезно някога.
 

Горе