[php] Variabele behouden in recursieve functie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dit is een functie waarmee ik aan de hand van een array een navigatiebalk probeer te genereren:
PHP:
1
2
3
4
5
6
7
8
9
10
function navbar($id, $array) {
  if($id > 0) {
    $out[] = $array[$id]['titel'];
    $par = $array[$id]['parent'];
    navbar($par, $array);
  } else {
    $out[] = 'Home';
    return $out;
  }
}


Maar nu wordt $out elke keer overschreven (en geeft dus altijd 'Home' terug). Moet ik $out eerst declareren als global om de array aan te vullen in plaats van te overschrijven? Of doe ik iets anders verkeerd?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Je kan $out natuurlijk ook als parameter meegeven met een default waarde. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Je bedoelt zoiets?
PHP:
1
2
3
4
5
6
7
8
9
10
function print_navbar($id, $array, $out = '') {
  if($id > 0) {
    $out[] = $array[$id]['titel'];
    $par = $array[$id]['parent'];
    print_navbar($par, $array, $out);
  } else {
    $out[] = 'Home';
    return $out;
  }
}


Maar helaas, dat werkt ook niet. Er moet toch een manier zijn om de waarden in zo'n array te bewaren?

Acties:
  • 0 Henk 'm!

  • pjotrk
  • Registratie: Mei 2004
  • Laatst online: 15-07 18:43
Met navbar bedoel je een soort kruimelpad? (aan de code te zien)
In dat geval heb je geen recursieve functie nodig.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?
$array = array(
           array('parent'=>null, 'title'=>'root'),
           array('parent'=>0, 'title'=>'Sub1'),
           array('parent'=>1, 'title'=>'Sub2'),
           array('parent'=>2, 'title'=>'Sub3'),
           array('parent'=>3, 'title'=>'Sub4')
         );

function navbar($id, $array) {
    $items = array();
    while ($array[$id] != null)
    {
        array_unshift($items, $array[$id]['title']);
        $id = $array[$id]['parent'];
    }
    return $items;
}

$navbar = navbar(4, $array);

echo implode(' => ', $navbar);
?>

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Met static kan je dit doen.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Dat zou ik normaal ook zeggen, maar kent PHP dat dan? Ik vind er niets over terug in de documentatie.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 16-09 16:02

JHS

Splitting the thaum.

NMe84 schreef op maandag 15 november 2004 @ 19:58:
[...]

Dat zou ik normaal ook zeggen, maar kent PHP dat dan? Ik vind er niets over terug in de documentatie.
Ik zou zeggen: probeer het :) . Maar php ondersteund idd static, net als global :) .

DM!


Acties:
  • 0 Henk 'm!

  • Sendy
  • Registratie: September 2001
  • Niet online
Verwijderd schreef op maandag 15 november 2004 @ 19:16:
Moet ik $out eerst declareren als global om de array aan te vullen in plaats van te overschrijven?
In navolging op mijn voorganger: probeer het eens.

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
NMe84 schreef op maandag 15 november 2004 @ 19:58:
[...]
Dat zou ik normaal ook zeggen, maar kent PHP dat dan? Ik vind er niets over terug in de documentatie.
Ik heb het ook nog niet in de documentatie gevonden/gezien maar het werkt wel degelijk.

Acties:
  • 0 Henk 'm!

  • semicolon
  • Registratie: Mei 2004
  • Niet online
http://nl3.php.net/language.variables.scope
Hier wordt 'static' uitgelegd voor PHP, en het werkt gewoon, en zou in dit geval ook moeten werken lijkt mij :)
Er staat zelfs een recursieve functie met static als voorbeeld..

[ Voor 25% gewijzigd door semicolon op 15-11-2004 20:51 . Reden: tikfout ]

:D/-<


Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Kunt ook een global variabele gebruiken :?

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
MisterData schreef op maandag 15 november 2004 @ 22:09:
Kunt ook een global variabele gebruiken :?
Static is in dit geval toch een stuk netter :)

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Alleen even opletten dat als je die functie nogmaals aanroept die static var nog steeds die waarde heeft ;)
Zelf zou ik gewoon die var meegeven aan de functie met eventueel een default waarde.

Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Verwijderd schreef op maandag 15 november 2004 @ 19:16:
[...]
Maar nu wordt $out elke keer overschreven (en geeft dus altijd 'Home' terug). Moet ik $out eerst declareren als global om de array aan te vullen in plaats van te overschrijven? Of doe ik iets anders verkeerd?
IMHO is by reference een goede oplossing :)

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
[edited again]
Dit zou het moeten doen...
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function navbar ($id, $array, $splitchar, $output='')
{

  $par = $array[$id]['parent'];
  $output .= ($id==0) 
         ? 'Home' 
         : $array[$id]['titel'] .$splitchar .navbar ($par, $array, $splitchar, $output);

  return $output;
}

function print_navbar($id, $array)
{
    $splitchar = '|'; 
          //of enig ander die niet voorkomt in de waarden in $array[$id]['titel']

    return explode($splitchar, navbar($id, $array, $splitchar));
}

[ Voor 157% gewijzigd door T-MOB op 16-11-2004 01:53 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • pjotrk
  • Registratie: Mei 2004
  • Laatst online: 15-07 18:43
Of vanaf het hoogste niveau beginnen met een array returnen :p
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?
$array = array(
           array('parent'=>null, 'title'=>'root'),
           array('parent'=>0, 'title'=>'Sub1'),
           array('parent'=>1, 'title'=>'Sub2'),
           array('parent'=>2, 'title'=>'Sub3'),
           array('parent'=>3, 'title'=>'Sub4')
         );

function navbar($id, &$array) {
    if ($array[$id]['parent'] === null) {
        return array($array[$id]['title']);
    } else {
        return array_merge( navbar($array[$id]['parent'], &$array), $array[$id]['title'] );
    }
}

$navbar = navbar(4, &$array);
echo implode(' => ', $navbar);
?>

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

T-MOB schreef op dinsdag 16 november 2004 @ 00:58:
[edited again]
Dit zou het moeten doen...
PHP:
1
function navbar ($id, $array, $splitchar, $output='')
Waarom zet je $output naar een lege string als het een array moet worden?
PHP:
1
function navbar ($id, $array, $splitchar, $output=array() )


Ik weet dat PHP het geen *** boeit welk type een var is, maar probeer daar zelf structuur in te houden als dat kan ;)

Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Kon het toch niet laten :Y)
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$nav = array();
$nav[0]['title'] = 'Home';
$nav[0]['parent'] = null;

$nav[1]['title'] = 'Sitemap';
$nav[1]['parent'] = 0;
$nav[2]['title'] = 'Contact';
$nav[2]['parent'] = 0;

$nav[3]['title'] = 'Postduif';
$nav[3]['parent'] = 2;
$nav[4]['title'] = 'Brief';
$nav[4]['parent'] = 2;
$nav[5]['title'] = 'Mail';
$nav[5]['parent'] = 2;

function navbar($id, &$nav, &$out, $first = true) {
    $out = ($first) ? array() : $out;
    $out[] = $nav[$id]['title'];
    if($nav[$id]['parent'] > -1) {
        navbar($nav[$id]['parent'], $nav, $out, false);
    }
    return $out;
}

echo '<pre>';
print_r(navbar(4, $nav, $out));
print_r(navbar(2, $nav, $out));
print_r(navbar(1, $nav, $out));
echo '</pre>';

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Erkens schreef op dinsdag 16 november 2004 @ 09:28:
[...]

Waarom zet je $output naar een lege string als het een array moet worden?
PHP:
1
function navbar ($id, $array, $splitchar, $output=array() )


Ik weet dat PHP het geen *** boeit welk type een var is, maar probeer daar zelf structuur in te houden als dat kan ;)
In de functie die je quote is output ook een string :> . Overigens mag je volgens mij in een een functiedecalaratie geen andere functies aanroepen. Dat geldt iig voor door jezelf gemaakte functies. $output=array() gaat denk ik niet werken...

Maargoed terug ontopic. Na gisteravond drie gedrochten van recursieve functie te hebben gebouwd denk ik dat het veel makkelijker kan:
PHP:
1
2
3
4
5
6
7
8
9
10
function navbar($id, $array)
{
    while ($id > 0)
    {
        $out[] = $array[$id]['titel'];
        $id = $array[$id]['parent'];
    }
    $out[] = 'Home';
    return $out;
}

[ Voor 4% gewijzigd door T-MOB op 16-11-2004 17:41 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

T-MOB schreef op dinsdag 16 november 2004 @ 17:39:
[...]


In de functie die je quote is output ook een string :> . Overigens mag je volgens mij in een een functiedecalaratie geen andere functies aanroepen. Dat geldt iig voor door jezelf gemaakte functies. $output=array() gaat denk ik niet werken...
ik had gewoon ff de verkeerde var, gebeurd jou zeker nooit :O
maar waarom zou $output=array() niet werken? dat is echt geen functie ofzo 8)7

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Erkens schreef op dinsdag 16 november 2004 @ 17:46:
[...]
ik had gewoon ff de verkeerde var, gebeurd jou zeker nooit :O
Tuurlijk gebeurt mij dat ook (sterker nog ik edit bijna elke post met code omdat ik foutjes zie :X ). Maar in mijn hele post stond geen geval van type-juggling (of hoe dat ook mag heten).
maar waarom zou $output=array() niet werken? dat is echt geen functie ofzo 8)7
Je hebt gelijk het werkt gewoon...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

T-MOB schreef op dinsdag 16 november 2004 @ 17:39:
[...]
...denk ik dat het veel makkelijker kan...
Netjes T-MOB :) Ik denk dat iedereen op het verkeerde been werd gezet door dat recursief/global verhaal.
Pagina: 1