1. <?php
  2. function bruttoAusrechnen($nettoBetrag, $steuerSatz, &$berechneteSteuer)
  3. {
  4. $berechneteSteuer = $nettoBetrag * $steuerSatz;
  5. $bruttoBetrag = $nettoBetrag + $berechneteSteuer;
  6. return $bruttoBetrag;
  7. }
  8. ?>

Schauen wir uns doch mal die oben stehende Funktion an. Eigentlich eine stink normale Funktion. Wobei, da hat sich ein & vor eine Variable geschlichen. Und das ist auch kein Typo, sondern dass soll auch noch so.
Was es damit aufsich hat, möchte ich im folgenden Beitrag kurz erläutern.

Wir möchten eine Funktion entwickeln (nein halt, entwickeln hört sich extrem kompliziert an, sagen wir schreiben), welche für uns einen Brutto-Betrag ausrechnet. Und weil wir ja nicht von gestern sind, soll die Funktion das nicht für irgendeinen Wert ausrechnen, sondern für einen von uns angegebenen Nettobetrag. Soweit, so gut:

  1. <?php
  2. function bruttoAusrechnen($nettoBetrag)
  3. {
  4. $berechneteSteuer = $nettoBetrag * 0.2;
  5. $bruttoBetrag = $nettoBetrag + $berechneteSteuer;
  6. return $bruttoBetrag;
  7. }
  8. ?>

Sieht schon ganz toll, und funktioniert auch ebenso toll. Allerdings haben wir noch ein Problem: was wenn wir die Funktion irgendwann mal dafür verwenden möchten, auch den Brutto-Betrag mit einem anderen Steuersatz auszurechnen? Die Lösung dafür ist natürlich genauso einfach: Wir übergeben eine zweite Variable, welche den Steuersatz beinhaltet.

  1. <?php
  2. function bruttoAusrechnen($nettoBetrag, $steuerSatz)
  3. {
  4. $berechneteSteuer = $nettoBetrag * $steuerSatz;
  5. $bruttoBetrag = $nettoBetrag + $berechneteSteuer;
  6. return $bruttoBetrag;
  7. }
  8. ?>

Ist schon eine ziemlich tolle Funktion die wir da programmiert haben. Verwendet wird sie by the way so:

  1. <?php
  2. $netto = 100;
  3. $steuer = 0.2;
  4. $brutto = bruttoAusrechnen($netto, $steuer);
  5.  
  6. //Man kann sich die Variablen auch sparen:
  7. $brutto = bruttoAusrechnen(100, 0.2);
  8. ?>

(Die Variablen sind bewusst anders benannt, um zu verdeutlichen dass sie nicht gleich heißen müssen)

Kurze Frage zwischendurch: Warum müssen wir der Funktion eigentlich Variablen über- bzw. mitgeben?
Wie wir wissen, sind in PHP Variablen standardmäßig nicht global. Das bedeuted, dass Variablen immer nur in einem begrenzten Bereich gültig (sprich verwendbar) sind. Das Beispiel soll verdeutlichen was damit gemeint ist:

  1. <?php
  2. function meineFunktion()
  3. {
  4. echo $meineVariable; //Es wird nichts ausgegeben, da die Variable meineVariable
  5. // in dieser Funktion nicht deklariert wurde.
  6. }
  7.  
  8. $meineVariable = "ABCDEF";
  9.  
  10. meineFunktion(); //Hier wird die Funktion aufgerufen.
  11.  
  12. echo $meineVariable; //Hier wird, wie erwartet ABCDEF ausgegeben, da die Variable
  13. //in diesem Bereich des Programmes deklariert wurde.
  14. ?>

Diese Limitation von PHP, ist eigentlich keine, sondern sogar ein Vorteil. Man müsste ja sonst aufpassen, dass man nicht ausversehen einen Variablenamen zweimal verwendet. Was passiert nun wenn man einer Funktion eine Variable übergibt? PHP kopiert den Inhalt der zu übergebenen Variable, und fügt den Inhalt dann in eine neue Variable, innerhalb der Funktion, wieder ein. Verändert man also innerhalb einer Funktion den Wert einer Variable, so wird der Wert der "Ursprungsvariable" in keinster weise beeinflusst.

Aber zurück zu unserem Beispiel. Wir haben jetzt eine Funktion, welche 2 Argumente erwartet. Einmal den Netto-Betrag und einmal den zu verwendenden Steuersatz. Daraufhin gibt uns dann die Funktion den berechneten Brutto-Betrag zurück. Was ist aber, wenn wir auch gleich noch die Steuer in € erhalten möchten?

Wie wir wissen, kann eine Funktion immer nur einen Wert zurückgeben. Was könnten wir also sonst noch so machen?

  • Eine neue, zweite, Funktion welche nur die Steuer berechnet
  • Verzweifeln
  • Eine Variable als global deklarieren, damit wir sie in der Funktion verwenden können (siehe oben)

Eine zweite Funktion bedeuted mehr Code, den jemand schreiben und später warten muss. Nix gut.
Verzweifeln ist generell keine gute Idee.
Eine Globale Variable ist für diesen Zweck auch nicht sehr schön, vor allem weil es sehr schnell unübersichtlich wird ("Ist in der Funktion jetzt die, die oder doch die Variable gemeint?"). Also auch nix gut.

Was man deshalb machen kann ist, einer Funktion nicht einen konkreten "Variablenwert" zu übergeben, sondern nur die "Adresse" zu einer Variable.

Variablen muss man sich vorstellen wir Schubladen (danke an Prof. Hofer für den treffenden Vergleich). Eine solche Schublade hat eine eindeutige Nummer (ihre Adresse) und in ihr kann natürlich irgend-etwas stehen.

Wenn man jetzt einer Funktion nicht den Wert einer Variable übergibt, sondern ihre Adresse, kann die Funktion damit tun was sie will. Eben auch darin selber Werte speichern. Und weil die Adresse zu der Variable sich ja nicht ändert, kann auf den (neuen) Wert dann auch außerhalb der Funktion zugegriffen werden. Und genau das macht das & vor einer Variable in einem Funktionsaufruf:

  1. <?php
  2. function bruttoAusrechnen($nettoBetrag, $steuerSatz, &$berechneteSteuer)
  3. {
  4. $berechneteSteuer = $nettoBetrag * $steuerSatz;
  5. $bruttoBetrag = $nettoBetrag + $berechneteSteuer;
  6. return $bruttoBetrag;
  7. }
  8.  
  9. $netto = 100;
  10. $steuer = 0.2;
  11. $berechnete_steuer = 0;
  12. $brutto = bruttoAusrechnen($netto, $steuer, &$berechnete_steuer);
  13. ?>

In unserem Beispiel hat dann $brutto einen Wert von 120 und $berechnete_steuer einen Wert von 20.

Und genau um das geht es. Zwei oder mehr Werte aus einer Funktion zu bekommen.