PHP
Home
PHP von der Kommandozeile
PHP und HTML im Zusammenspiel
Variablen und Zuweisungen
Arrays
Vergleichsoperatoren
Verzweigungen
Schleifen
Funktionen
Datei schreiben
Datei lesen
Formulare verarbeiten
Sortieren von Dateinamen
Anzeige:
PHP Kurse für Anfänger und Fortgeschrittene
Kontakt
Haftung
Impressum
Problem Hilfe Startseite
|
Funktionen
Eine höhere Programmiersprache ohne Funktionen ist nicht denkbar.
Sobald man größere Programme erstellt, kommt es immer wieder
vor, dass sich Code wiederholt, d.h. der Code ist gleich bis auf
verschiedene Werte.
if ($a >= $b) {
$ergebnis = $a;
} else {
$ergebnis = $b;
}
|
Wie man leicht sehen kann enthält $ergebnis nach Ausführung
der if-Anweisung den Wert der Variablen mit dem höchsten Wert.
Stellen wir uns nun vor, dass an einer anderen Stelle eines
größeren Programmes folgender Code steht:
if ($x >= $y*7) {
$ergebnis = $x;
} else {
$ergebnis = $y*7;
}
|
Wenn $y * 7 größer als $x ist, enthält $Ergebnis nach
der Ausführung der if-Anweisung den Wert $y * 7 ansonsten den Wert
von $x.
Funktion:
Eine Funktion besteht aus
einem Funktionskopf und einem Funktionsrumpf.
Der Funktionskopf seinerseits besteht aus dem Schlüsselwort
function , welches dem Interpreter sagt, dass eine
Funtionsdefinition
beginnt. Dann folgt der frei wählbare Name der Funktion.
Gültige Funktionsnamen müssen mit einem Unterstrich "_"
(underscore) oder einem Buchstaben beginnen, danach können weitere
Buchstaben, Ziffern oder der Unterstrich in beliebiger Reihenfolge
kommen.
Nach dem Namen folgt zwischen einem runden Klammernpaar eine mittels
Kommata separierte Parameterliste, d.h. die Werte und Variablen, die an
den Funktionsrumpf übergeben werden. Der Funktionskopf bestimmt,
wie die Funktion aufgerufen wird, nämlich ähnlich wie in der
Funktionsdefinition aber ohne das Schlüsselwort function .
Im Funktionsrumpf befindet sich der Code, der bei einem Aufruf
ausgeführt wird. Eine Funktion muss sicherstellen, dass sie
jeweils mit einer return-Anweisung endet. In der Return-Anweisung steht
das Ergebnis der Funktions, was an die aufrufende Stelle
zurückgegeben wird.
function
funktionsname(parameter1,parameter2,...) {
... Anweisungen inklusive einer return-Anweisung...
}
|
Für die beiden eingangs aufgeführten
if-Anweisungen schreiben wir die Funktion maxn(), die wir in ein
komplettes Programm einbetten, dass man die Berechnung nachvollziehen
kann:
<?
function maxn($x, $y) {
if ($x >= $y) {
$ergebnis = $x;
} else {
$ergebnis = $y;
}
return $ergebnis;
}
$a = 3;
$b = 4;
$x = 12;
$y = 2;
$ergebnis = maxn($a, $b);
echo "$ergebnis\n";
$ergebnis = maxn($x, $y*7);
echo "$ergebnis\n";
?>
|
Anmerkung: Der Name maxn statt max wurde
benutzt, da es schon eine
Funktion in PHP mit dem Namen max gibt.
Speichert man obiges Skript unter dem Namen maxn.php und ruft man
das Programm mit "php5 maxn.php" auf erhält man folgende Ausgabe:
> php5 function.php
4
14
>
|
Parameterübergabe
Aufruf durch Wertübergabe (Call by Value)
Auf einen Aspekt sind wir bisher noch nicht eingegangen: In der obigen
Funktion maxn gibt es Parameter mit den
Variablennamen $x und $y, ebenso
gibt es im aufrufenden Hauptprogramm zwei Variablen $x
und $y. Es stellt sich die Frage, ob die Variable $x
innerhalb der Funktion die gleiche ist, wie das $x des
Hauptprogramms. In der Funktion maxn
können wir allerdings dies nicht feststellen, da es prinzipiell
egal ist, da $x und $y im Funktionsrumpf
nicht verändert werden. Wir schauen uns deshalb eine andere
Funktion an:
<?
function g_var($x) {
$x = 18;
echo "Wert von x in gvar: $x\n";
return 0;
}
$x = 3;
echo "Wert von x vor Aufruf g_var: $x\n";
g_var($x);
echo "Wert von x nach Aufruf g_var: $x\n";
?>
|
Führt man dieses Programm (in Datei g_var.php) aus, erhält
man folgende Ausgabe:
> php5 function2.php
Wert von x vor Aufruf g_var: 3
Wert von x in gvar: 18
Wert von x nach Aufruf g_var: 3
>
|
Wäre die Variable $x innerhalb der Funktion die
gleiche wie außerhalb, so hätte sie nach dem Aufruf den Wert
18 und nicht 3, wie obiger Aufruf zeigt.
Das heißt ganz allgemein, dass bei PHP beim Aufruf einer Funktion
normalerweise eine Wertübergabe (call by value) erfolgt. Anders
ausgedrückt: Falls ein gleicher Name innerhalb und außerhalb
existiert, bezeichnen sie dennoch verschiedene Speicherstellen.
Referenzübergabe (Call by Reference)
Manchmal will man aber, dass innerhalb einer Funktion eine bestimmte
Variable verwendet und auch mit wirkung nach außen hin
verändert wird. Will man diesen Effekt, so setzt man nur ein
Et-Zeichen "&" vor die entsprechende Variable. Betrachten wir
folgendes veränderte Beispiel:
<?
function g_var(&$x) {
$x = 18;
echo "Wert von x in gvar: $x\n";
return 0;
}
$x = 3;
echo "Wert von x vor Aufruf g_var: $x\n";
g_var($x);
echo "Wert von x nach Aufruf g_var: $x\n";
$y = 4;
echo "Wert von y vor Aufruf g_var: $y\n";
g_var($y);
echo "Wert von y nach Aufruf g_var: $y\n";
?>
|
Was wird jetzt wohl für $x und $y ausgegeben?
Man kann es sich so vorstellen, als würde beim Aufruf der
Funktion g_var jedes Vorkommen der Variablen $x
durch die entsprechende Variable des Aufrufs ersetzt. Korrekter ist es,
wenn man sich vorstellt, dass die Variable $x auf die
gleiche Speicherstelle wie die Variable im Aufruf zeigt.
Man erhält deshalb folgende Ausgabe:
> php5 function3.php
Wert von x vor Aufruf g_var: 3
Wert von x in gvar: 18
Wert von x nach Aufruf g_var: 18
Wert von y vor Aufruf g_var: 4
Wert von x in gvar: 18
Wert von y nach Aufruf g_var: 18
>
|
Rekursive Funktionen
Eine sehr elegante Methode zur Lösung bestimmter Probleme stellt
die rekursive Programmierung dar. Man spricht von einer rekursiven
Funktion, wenn in ihrem Rumpf wieder ein Aufruf "von sich selbst"
erfolgt.
Als Paradebeispiel für solche Funktionen wird in der
Informatik die Fakultätsfunktion verwendet. Die Fakultät
stammt aus der Kombinatorik . Sie dient dazu die Anzahl von
verschiedenen Permutationen zu berechnen.
Mathematische Definition einer Permutation: Unter einer Permutation
(lateinisch permutare - vertauschen) versteht man eine Neuanordnung
einer Anordnung einer Menge durch Vertauschung ihrer Elemente.
Hat man zum Beispiel die Menge der Buchstaben a, b, c und d und die
Anordnung abcd, dann handelt es sich bei acbd um eine Permutation von
abcd.
Die Menge aller Permutationen von abcd findet man im nächsten
Diagramm:
Permutation von abcd
a
|
b
|
c
|
d
|
d
|
c
|
c
|
b
|
d
|
d
|
b
|
d
|
b
|
c
|
c
|
b
|
b
|
a
|
c
|
d
|
d
|
c
|
c
|
a
|
d
|
d
|
a
|
d
|
a
|
c
|
c
|
a
|
c
|
a
|
b
|
d
|
d
|
b
|
b
|
a
|
d
|
d
|
a
|
d
|
a
|
b
|
b
|
a
|
d
|
a
|
b
|
c
|
c
|
b
|
b
|
a
|
c
|
c
|
a
|
c
|
a
|
b
|
b
|
a
|
Wenn man sich obiges Diagramm anschaut, sieht man, dass mit jeder der 4
Buchstaben der ersten Spalte mit jeweils genau 3 Buchstaben kombiniert
werden kann, also "a" z.B. mit "b", "c" und "d". Jedes Element (jeder
Buchstabe) der zweiten Spalte kann mit jeweils zwei anderen Buchstaben
kombiniert werden. Für die Buchstaben in der dritten Zeile bleibt
nur noch genau eine Kombinationsmöglichkeit übrig. Wir sehen,
dass wir 24 Zeilen in der vierten Spalte haben, was auch der Anzahl der
Permutationen entspricht. Die Anzahl der Permutationen errechnet sich
auch, wie wir eben gesehen haben, aus dem Produkt 4 * 3 * 2 * 1.
Hätten wir 5 Buchstaben genommen, hätten wir 5*4*3*2*1 = 120
verschiedene Permutationen.
Ganz allgemein gilt: n Objekte lassen sich n*(n-1)* ... * 2 * 1 Mal
kombinieren. Für dieses Produkt hat man in der Mathematik die
Schreibweise n! eingeführt, d.h. n! ist eine abkürzende
Schreibweise für n*(n-1)* ... * 2 * 1.
Es gilt: n! = n * (n-1)! für n > 1
Damit hat man das Problem reduziert, d.h. wenn man das Ergebnis von
(n-1)! kennt, kann man durch Multiplikation mit n das Ergbnis von n!
berechnen.
0! ist als 1 definiert.
Die Fakultätsfunktion:
<?
# rekursive Version:
function fac ($n) {
if ($n == 0) {
return 1;
} else {
return fac($n - 1) * $n;
}
}
# einlsesn des Argumentes von der Shell
$in = fscanf(STDIN, "%d\n");
$res = fac($in[0]);
echo "fac($in[0]) = $res\n";
?>
|
Obige Funktion darf natürlich nur für ganze Zahlen die
größer oder gleich Null sind aufgerufen werden. In diesem
Fall ist sichergestellt, dass die Funktion terminiert, denn in jedem
Schritt wird fac() mit einem um 1 verminderten Parameter aufgerufen,
und zwar solange bis der Parameter 0 ist. Iterativ sieht ein Programm,
welches die Fakultätsfunktion berechnet sofort komplizierte und
vor allem weniger elegant aus:
<?
# iterative Version:
function fac_iterativ($n) {
$fac=1;
for ($i=2; $i <= $n; $i++) {
$fac = $fac * $i;
}
return $fac;
}
$in = fscanf(STDIN, "%d\n");
$res = fac_iterativ($in[0]);
echo "fac_iterativ($in[0]) = $res\n";
?>
|
|