toscho.design

PHP-Funktion alternate()

Diese Funktion benutze ich in fast jedem PHP-Projekt. Sie nimmt beliebig viele Werte entgegen und gibt sie einzeln bei jedem Aufruf zurück.

/**
 * Alterniert zwischen beliebig vielen Werten.
 *
 * @author Thomas Scholz <http://toscho.de>
 */
function alternate ()
{
    static $i = 0;
    $args = func_get_args();
    return $args[$i++ % (func_num_args())];
}

Anwendungsbeispiel

Denken wir uns einen Array, den wir als Liste ausgeben wollen:

$tolist = array('eins', 'zwei', 'drei', 'vier');

Wir wollen die Listenpunkte weiterhin mit drei abwechselnden Farben hinterlegen, brauchen also drei Klassen, die wir mit CSS ansprechen können.

Das geht jetzt ganz einfach:

$str = "<ul>\n";
foreach ($tolist as $item)
{
    $str .= '  <li class="' . alternate('a', 'b', 'c') . "\">$item</li>\n";
}
$str .= '</ul>';
echo $str;

Das ausgegebene Markup sieht nun so aus:

<ul>
  <li class="a">eins</li>
  <li class="b">zwei</li>
  <li class="c">drei</li>
  <li class="a">vier</li>
</ul>

Natürlich arbeitet die Funktion nicht nur mit Strings, sondern mit beliebigen Typen: Arrays, Zahlen oder Objekten.

Einfache Variante

Wenn wir nur zwischen zwei Werten abwechseln wollen, geht es so schneller:

$str = "<ul>\n";
foreach ($tolist as $item)
{
    $str .= '  <li ' . ( ($i++%2==0) ? '' : ' class="odd"') . ">$item</li>\n";
}
$str .= '</ul>';
echo $str;

Hierbei müssen wir freilich darauf achten, daß die Variable $i nicht an anderer Stelle im selben Namensraum benutzt wird. Das Verkapseln in einer eigenen Funktion mag also auch bei so einfachen Fällen der sicherere Weg sein.
Oder wir geben der Variable einen Namen, den sehr wahrscheinlich niemand sonst benutzt. Das finde ich aber nicht sehr … sauber.

2 Kommentare

  1. mantiz am 20.03.2009 · 12:41

    Hi,

    bin gerade durch das XHTML-Forum mal wieder auf Deiner Seite gelandet und da ist mir dieser Artikel aufgefallen. :)
    Daraufhin habe ich mir kurz Gedanken dazu gemacht, ob ich das auch brauchen könnte, da ich das bisher immer so löse, wie in Deiner "Einfachen Variante".

    Dabei bin ich auf folgende Lösung gestoßen, die ich wohl in Zukunft verwenden werde:

    $css = array('a', 'b', 'c');
    $list = array(1, 2, 3, 4);
    echo "<ul>\n";
    foreach ($list as $i => $item) {
       echo "<li class=\"", $css[$i % count($css)], "\">", $item, "</li>\n";
    }
    echo "</ul>\n";
    

    Dann braucht man nicht extra eine Funktion dafür. ;-)

  2. Thomas Scholz am 20.03.2009 · 13:17

    Stimmt, man muß nicht unbedingt eine Funktion benutzen. Wie ich im letzten Absatz angedeutet habe, kommt es immer darauf an, in welchem Namensraum man arbeitet. Im globalen Namensraum würde ich keinesfalls neue Variablen einführen; innerhalb einer Funktion hingegen kann man das durchaus machen.

    Der Charme der separaten Funktion liegt im überschaubaren Quelltext. Dafür ist sie vermutlich einen Tick langsamer.