---
title: "Rekursiv funktion, alternerande rader"
type: "forum-thread"
url: "https://www.webforum.nu/amne/php/191418-rekursiv-funktion-alternerande-rader"
topic: "PHP"
topic_url: "https://www.webforum.nu/amne/php"
author: "MickeA.com"
published: "2013-06-13T13:49:44.000Z"
updated: "2013-06-13T23:18:29.000Z"
replies: 2
views: 2257
page: 1
pages: 1
language: "sv-SE"
site: "webForum — webforum.nu"
rights: "Upphovsrätten till varje inlägg tillhör dess författare."
attribution: "Citera som: webForum, https://www.webforum.nu/amne/php/191418-rekursiv-funktion-alternerande-rader"
---

# Rekursiv funktion, alternerande rader

## #1 — MickeA.com, 2013-06-13T13:49Z

Tja,

Håller på att bli tokig... Skriver ut en tabell rekurisvt och behöver fixa alternerande rader. Blir fel eftersom funktionen kallar på sig själv mellanåt.

```php
public function OverviewByType($Data, $Type = null, $Depth = 0){
	$Sb = "";

	$Row = <<<EOT
		<tr class="%s">\n
		<td class="ColumnCBox">%d</td>\n
		<td class="ColumnTitle" style="padding-left: %dpx;"><a href="{$Path}content.add.php?Do=Edit&amp;ContentId=%d"><strong>%s</strong></a>%s%s</td>\n
		<td>%s</td>
		<td><a href="%s" title="">%s</a></td>
		<td>%s</td>
		</tr>\n
EOT;
	
	
	$Depth++;
	
	Static $Alt = 0; // <-- 'Static' skulle göra susen läste jag, men fungerar ej.

	foreach($Data as $Item){
		
		$Class = ($Alt%2 == 0 ? "row-odd" : "row-even"); // <-- Här sätts klassen.
		$Sb .= sprintf($Row, $Class);
		$Sb .= $this->OverviewByType($Item['Child'], $Type, $Depth);
		$Alt++;
	}
	return $Sb;
}
```

Koden ovan är inte helt komplett, men visar det som är viktigt i sammanhanget.

Läste på StackOverflow (<http://stackoverflow.com/questions/5473633/php-alternate-row-color-help?answertab=active#tab-top>) att det ska räcka med att deklarera alt-variabeln som **static** men det fungerar inte i mitt fall ovan.
 
Några förslag på hur man löser det? Jag menar det bör ju gå på **något** sätt, eller hur?

Tack!

Permalänk: https://www.webforum.nu/p/191418

## #2 — nitro2k01, 2013-06-13T15:50Z

Static? Näe... Det betyder ju att en variabel deklareras en gång för hela klassen istället för separat per objekt. Det bör inte alls göra någon skillnad i ditt fall, så länge allt sker inom ett och samma objekt. Dessutom, att deklarera en variabel som static inuti en funktion, sense it does not make! Variabler i en funktion deklareras ju separat för anrop till funktionen.

Men, så till att lösa ditt problem. Allra helst bör du nog lösa det i ren CSS, typ:

```
tr.klassnamn:nth-child(even) { ... }
tr.klassnamn:nth-child(odd) { ... }
```

Men om du inte vill göra detta av någon anledning eller bara är nyfiken på hur man eventuellt kan göra i PHP...

Ett sätt är att deklarera variabeln som en objetvariabel (eller vad det nu heter), dvs ute i klass-scopet, utanför funktionen. (Jag tror man kan göra så i PHP iaf.) Men ska du göra flera körningar så bör du nolla funktionen innan varje ny körning, annars behåller den det sista värdet sen sist. Kanske inte helt optimalt.

```php
$Alt = 0;

public function OverviewByType($Data, $Type = null, $Depth = 0){
```

Min favorit är nog att passa variabeln som en referens. Med andra ord skickar du runt samma variabel. Typ:

```php
public function OverviewByType($Data, $Type = null, $Depth = 0, &$Alt = 0){ 
    $Sb = ""; 

    $Row = <<<EOT 
        <tr class="%s">\n 
        <td class="ColumnCBox">%d</td>\n 
        <td class="ColumnTitle" style="padding-left: %dpx;"><a href="{$Path}content.add.php?Do=Edit&amp;ContentId=%d"><strong>%s</strong></a>%s%s</td>\n 
        <td>%s</td> 
        <td><a href="%s" title="">%s</a></td> 
        <td>%s</td> 
        </tr>\n 
EOT; 
     
     
    $Depth++; 

    foreach($Data as $Item){ 
        $Class = ($Alt++%2 == 0 ? "row-odd" : "row-even"); // <-- Här sätts klassen. 
        $Sb .= sprintf($Row, $Class); 
        $Sb .= $this->OverviewByType($Item['Child'], $Type, $Depth, $Alt); 
    } 
    return $Sb; 
}
```

Saker värda att notera med koden ovan. 
1) & betyder att variabeln skickas som referens, alltså att förändringar i anropet bevaras.
2) "= 0" sätter ett standardvärde som används om det argumentet utelämnas, vilket är användbart för det första anropet. Utan detta skulle man behöva göra en liten krusidull vid det första anropet:

```php
$AltInitial = 0;
$this->OverviewByType($Item['Child'], $Type, $Depth, $AltInitial);
```

Enbart

```php
$this->OverviewByType($Item['Child'], $Type, $Depth, 0);
```

Skulle inte fungera eftersom man måste skicka med n variabel, inte bara ett värde.
3) Jag har flyttat på inkrementeringen eftersom det är problematiskt att ha den sist i loopen vid ett rekursivt anrop. Strikt sett behöver du inte använda den kluriga ++ notationen på samma rad som resten av grejerna, utan du kan gott flytta ut **$Alt++** till en egen rad.

Men oavsett hur resten av koden ser ut, måste inkrementeringen ske **innan** det rekursiva anropet. Annars komemr ingen inkrementering ske innan den första raden i ett rekursivt anrop skrivs ut, och på samma sätt kommer två eller fler inkrementeringar ske vid returen.

Permalänk: https://www.webforum.nu/p/2312854

## #3 — MickeA.com, 2013-06-13T23:18Z

Grymt, tack!

Dumma mig... Testade tidigare att skicka med Alt-värdet in i funktionen, fast med felen:

- Glömde &-tecknet fram *$Alt = 0*.
- Hade *$Alt++;* efter det rekursiva anropet.

Det var rätt fram att det blev ett visst antal rader, med olika djup. Nu fungerar dock allt precis som det ska.

Tack!

Permalänk: https://www.webforum.nu/p/2312857

---

Tråden på webben: https://www.webforum.nu/amne/php/191418-rekursiv-funktion-alternerande-rader
