• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

PHP functionen

Flemli200

Mitglied
Hi,

ich hab einfach mal eine frage...

was ist der vorteil einer PHP function?

kann ich nicht auch einfach eine if-abfrage starten und dann wenn das zutrifft eine datei includieren?

also anstatt
bla_function.php
PHP:
class eins
{
 function eins($zahl)
 {
   $einszwei=$zahl;
 }
}

PHP:
include=bla_function.php
$x=2;
if(isset($x))
{
$y=new eins($x);
}

einfach

PHP:
$x=2;
if(isset($x))
{
 include(bla.php);
 $y=$bla;
}
bla.php:
PHP:
$bla=$x;

schreiben??

Is ein sehr einfach gehaltener code (und möglicherweise auch nich ganz richtig)
aber nur zum verständnis... was hat die function für vorteile??
 
Hallo Flemli200,

die Möglichkeit der Funktionsdeklaration ist nur ein kleiner Teil der angebotenen Programmarchitektur in PHP. Wenn es daran geht ein großen Projekt übersichtlich, nachhaltig und effizient aufzubauen und zu strukturieren ist es sehr von Vorteil die objekt-orientierte Modellierung zu nutzen, mit u.a. eigenen Funktionen.

Ich weiß jetzt nicht, ob du nur auf das function-Schlüsselwort hinauswillst oder auch auf Klassen, Interfaces, ... aber eigene Funktionen sind vorallem dann nützlich, wenn man einen algorithmischen Ablauf während der Programmlaufzeit mehrmals benutzt.

In dem Zusammenhang wäre die objekt-orientierte Programmierung (OOP) recht interessant:
Objektorientierte Programmierung

Und ein kürzlich von mermshaus verfasster Eintrag zur Softwarearchitektur mit MVC:
MVC

Gruß
 
naja... diesen Ablauf, kann ich doch auch komplett in eine externe Datei schreiben und die Datei einfach includen oder?
Die Datei mit der funktion muss ich doch auch immer wenn ich sie benutzen will includen...
nach meinem momentanen Wissensstand seh ich da keinen vorteil.
 
Die Variablen in einer Funktion sind nur lokal ansprechbar.
PHP:
function gebeZahlen(){
	$i = 1;
	while($i <= 10)
		echo $i."\n";
}
Würdest du dies includen, wäre die Variable $i global und würde ggf. eine andere Variable überschreiben, bei jedem Aufruf.

Bei einem größen Projekt sind die Vorteile leichter sichtbar.
 
Also ist das class function modell nur sinnvoll, wenn ich variabeln mehrmals benutze oder einfach mehrere gleichnamige variabeln verwenden moechte...

Danke... mir waren class und functionen noch komplett fremd...

Werd mal versuchen n bissl mehr damit zu arbeiten ;)
 
In einem MVC hast du (meistens) mehrere Controllers. Jetzt kannst du zB eine abstracte Controller Klasse schreiben, die ihre Methoden und Eigenschaften an alle Controller vererbt.

PHP:
<?php
abstract class abstractController
{
    protected function includeDisplay($fileName)
    {
        require_once("/views/".$fileName.".php");    
    }
    
    protected function includeModel($fileName)
    {
        require_once("/models/".$fileName.".php");          
    }    
}
?>
Und die verschiedenen Controller bekommen nun mittels Vererbung die Eigenschaften von abstractController


Beispiel
PHP:
<?php
class indexController extends abstractController
{
    public function __construct()
    {
        $this->includeDisplay("indexView");
    }
}
?>
Jeder Controller, der vom Abstrakten Kontroller erbt, hat alle Methoden und Eigenschaften die eben im Abstrakten Kontroller stehen - dadurch spart man sich enorm viel Schreibarbeit, man definiert Methoden, die jeder Controller braucht in einem "Über-Kontroller" und mann muss ihn nur einmal definieren.
 
Versuch doch mal in deinem Beispiel von oben (include (bla.php); der Variablen $delta oder irgend einem anderen Wert $x zuzuweisen, dann erkennst du den Vorteil von Funktionen recht deutlich.
Bei einem include ist die Deklaration der Variablen starr, bei Funktionen nicht.
 
Ja. Der Punkt ist, dass du bei Includes keinen abgeschotteten Gültigkeitsbereich für Variablennamen hast.

Sagen wir, du möchtest die dritte Potenz (x³) der ersten 10 positiven Ganzzahlen (1-10) ermitteln und ausgeben.

Dein Hauptprogramm sähe wahrscheinlich etwa so aus:

PHP:
<?php

for ($i = 1; $i <= 10; $i++) {
    $base = $i;
    $exp  = 3;
    include 'inc.exp.php';
    echo $result . '<br>';
}

Das Script in inc.exp.php erwartet, dass die Werte für Basis und Exponent in den Variablen $base und $exp vorliegen. Es füllt dann $result mit dem entsprechenden Ergebnis.

Der Code in inc.exp.php:

PHP:
<?php

$result = $base;

for ($i = 0; $i < $exp; $i++) {
    $result *= $base;
}

if ($exp === 0) {
    $result = 1;
}

Das ergibt beim Ausführen allerdings eine Endlosschleife.

PHP führt im Prinzip diesen Code aus:

PHP:
<?php

for ($i = 1; $i <= 10; $i++) {
    $base = $i;
    $exp  = 3;


        $result = $base;

        for ($i = 0; $i < $exp; $i++) {
            $result *= $base;
        }

        if ($exp === 0) {
            $result = 1;
        }
        

    echo $result . '<br>';
}

In der inneren for-Schleife wird $i immer wieder auf den Wert 3 gesetzt (der Wert von $exp). Und wenn $i den Wert 3 hat, bricht die äußere Schleife logischerweise nicht ab.

Wie lösen wir das Problem?

Wir nennen $i in der inkludierten Datei einfach $j. Könnten wir machen. Dann müssten wir allerdings aufpassen, das Include nie in eine Schleife zu schreiben, die mit $j zählt. Das mag in diesem simplen Fall eine Möglichkeit sein, aber je komplexer die Anwendung wird, desto mehr Variablennamen verbauen wir uns auf diese Weise.

Wir speichern bei Aufruf der Include-Datei alle gesetzten Variablen auf einem Stack (eine Art Zwischenspeicher) und „restaurieren“ sie am Ende der Include-Datei wieder. Das liest sich etwas kompliziert und diese Lösung ist auch nicht ganz einfach. Im folgenden Beispiel sind die drei Variablen $__STACK, $__IN und $__OUT interne, reservierte Variablen, die nur zum Datenaustausch zwischen Includes und dem eigentlichen Programm genutzt werden sollen.

inc.exp.php:

PHP:
<?php

unset($__OUT);                   # Verhindert, dass $__OUT bei extract() über-
                                 #   schrieben wird
$__STACK[] = get_defined_vars(); # Sämtliche definierten Variablen auf Stack
                                 #   schieben



$base = $__IN[0];                # 1. Übergabeparameter ist Basis
$exp  = $__IN[1];                # 2. Übergabeparameter ist Exponent



$result = $base;                 # Dieser Teil wie gehabt. Die hier eingesetzten
                                 #   lokalen Variablen werden beim Aufruf von
for ($i = 0; $i < $exp; $i++) {  #   extract() wieder mit denjenigen Werten
    $result *= $base;            #   überschrieben, die sie vor der Ausführung
}                                #   des Include-Codes hatten

if ($exp === 0) {
    $result = 1;
}



$__OUT[0] = $result;             # Ergebnis der Berechnung in Variable $__OUT
                                 #   speichern
extract(array_pop($__STACK));    # Alten Zustand aller Variablenwerte von vor
                                 #   dem Ausführen des Includes wiederherstellen

Und der Aufruf:

PHP:
<?php

// Reservierte Variablen

$__STACK = array();
$__IN    = array();
$__OUT   = array();



for ($i = 1; $i <= 10; $i++) {
    $base = $i;
    $exp  = 3;

    $__IN[0] = $base;      # Beim Einbinden des Includes werden die Übergabewer-
    $__IN[1] = $exp;       #   te in der Variablen $__IN gespeichert
    include 'inc.exp.php';
    $result = $__OUT[0];   # Die Rückgabe liegt äquivalent dazu in $__OUT vor
    
    echo $result . '<br>';
}

Auf diese Weise sind Includes schachtelbar. Hier ein Include, das zu einer Zahl eine andere Zahl addiert:

PHP:
<?php

unset($__OUT);                   # Verhindert, dass $__OUT bei extract() über-
                                 #   schrieben wird
$__STACK[] = get_defined_vars(); # Sämtliche definierten Variablen auf Stack
                                 #   schieben



$n = $__IN[0];                   # 1. Übergabeparameter ist Ausgangszahl
$k = $__IN[1];                   # 2. Übergabeparameter ist zu addierende Zahl



$result = $n;
                          
for ($i = 0; $i < $k; $i++) {
    $result++;
}                         



$__OUT[0] = $result;             # Ergebnis der Berechnung in Variable $__OUT
                                 #   speichern
extract(array_pop($__STACK));    # Alten Zustand aller Variablenwerte von vor
                                 #   dem Ausführen des Includes wiederherstellen

Dieses Include in inc.exp.php integriert:

PHP:
<?php

unset($__OUT);                   # Verhindert, dass $__OUT bei extract() über-
                                 #   schrieben wird
$__STACK[] = get_defined_vars(); # Sämtliche definierten Variablen auf Stack
                                 #   schieben



$base = $__IN[0];                # 1. Übergabeparameter ist Basis
$exp  = $__IN[1];                # 2. Übergabeparameter ist Exponent



$result = $base;                 # Dieser Teil wie gehabt. Die hier eingesetzten
                                 #   lokalen Variablen werden beim Aufruf von
for ($i = 0; $i < $exp; $i++) {  #   extract() wieder mit denjenigen Werten
    $result *= $base;            #   überschrieben, die sie vor der Ausführung
}                                #   des Include-Codes hatten

if ($exp === 0) {
    $result = 1;
}



$__IN[0] = $result;
$__IN[1] = 10;
include 'inc.addk.php';
$result = $__OUT[0];



$__OUT[0] = $result;             # Ergebnis der Berechnung in Variable $__OUT
                                 #   speichern
extract(array_pop($__STACK));    # Alten Zustand aller Variablenwerte von vor
                                 #   dem Ausführen des Includes wiederherstellen

Die Pointe dabei ist natürlich, dass PHP mit der Funktionssyntax genau dieses Zwischenspeichern bereits belegter Variablen und die Zuweisung der Werte für $__IN und $__OUT automatisch übernimmt.

PHP:
<?php

function addk($n, $k)
{
    $result = $n;

    for ($i = 0; $i < $k; $i++) {
        $result++;
    }

    return $result;
}

function exponent($base, $exp)
{
    $result = $base;             

    for ($i = 0; $i < $exp; $i++) {
        $result *= $base;
    }

    if ($exp === 0) {
        $result = 1;
    }

    $result = addk($result, 10);

    return $result;
}



for ($i = 1; $i <= 10; $i++) {
    $result = exponent($i, 3);

    echo $result . '<br>';
}

Intern passiert dabei grob das, was ich mit $__STACK, $__IN und $__OUT ziemlich vereinfacht umrissen habe.

Glücklicherweise hatten die Entwickler des PHP-Interpreters (wie die Entwickler fast jeder anderen Programmiersprache) Mitleid und haben dieses Verwalten der Variablen über spezielle Syntaxkonstrukte (function) abstrahiert.

- Unterprogramm
 
Zurück
Oben