Wann benutzt man OOP

Hey,

also ich habe mir jetzt mal die Grundliegenden Dinge über OOP angelesen und würde gerne mal Testen ob ich das uch so verstanden habe und umsetzen kann :wink:
Allerdings wann benutzte ich den OOP? Angenommen ich würde ein Kontaktformular schreiben, kann man sowas dann auch in OOP schreiben und z.B. durch folgenden Code erstellen lassen?

[PHP]
$kontakt1 = new Kontakrformular;
$kontakt1 → setEmpfänger(‚e-mail@adresse.de‘);
$kontakt1 → setCaptcha(‚ein‘);
[/PHP]

Wie muss ich das dann aufbauen, dass ich das mit folgenden Code erstellen kann?
Muss ich dann alles in die Klasse "Kontaktformular packen?

Also
[PHP]
class Kontaktformular
{
function setEmpfänger($empfänger) {

}

 function setCaptcha($status) {
      ....
 }

}
[/PHP]

Und wie schaffe ich dann, dass das ganze auf den Bildschirm erscheint wenn ich nur

[PHP]
$kontakt1 = new Kontaktformular;
[/PHP]

eingebe und am Ende aber ein Komplettes Kontaktformular habe.
Geht das in der Klasse durch __construct?

liebe Grüße

Edit:
Mir ist aufgefallen, dass der erste Absatz wiedersprüchlich klingt, also cih habe mir das gnaze schon angelesen allerdings war das alles nur Theorie und ich habe nicht richtig verstanden wann ich das Konkret einsetzen kann :wink:

Naja, also eine Möglichkeit wäre (das ist wohl das einfachste), wenn du dem Konstruktor gleich ein paar Parameter mitgibst.

Beispiel:
[php]class Kontaktformular
{
public function __constructor($mailto, $b_captcha)
{
$this->outputForm($mailto); // $mailto könntest du auch als Klassenvariable übernehmen

        if ( $b_captcha )
            $this->outputCaptcha();
    }
...

}[/php]Wenn dus machen willst, wie du beschrieben hast (erst Objekt erstellen, dann Eigenschaften setzen), dann brauchst du noch eine Methode, die du danach aufrufst, um das Output zu erstellen.

Grüße
Voodoo

Ok, erst mal vielen Dank.
Also der Konstruktor bildet mir das ganze auf den Schirm ab. Und die Methoden kommen nach dem Konstruktor?

[PHP]
class Kontaktformular
{
public function __constructor($mailto, $b_captcha)
{
$this->outputForm($mailto); // $mailto könntest du auch als Klassenvariable übernehmen

        if ( $b_captcha )
            $this->outputCaptcha();
    }

outputForm ($was-man-braucht) {

}

}
[/PHP]
Und da man ja ein Captcha vielseitig einsetzen kann, kann ich dieses dann Vererben?

[PHP]
class Captcha {
public $variable;

 private function outputCaptcha {
     ....
 }

}

class Kontaktformular extends Captcha {
public function __constructor {
//wie bekomme ich jetzt hier das Captcha rein?
//so?

     outputCaptcha();
 }

}[/PHP]

Und wann sollte ich eine Methode auf Private setzen? Und wann auf Public?

Also zunächst mal müsstest du die Captcha-Klasse in eine andere Datei packen, wenn du den Output nicht zwischenspeicherst, weil du ja damit auch das Bild generieren willst. Wenn du aber Output buffer benutzt, könntest du auch einfach nach der Ausgabe des Bildes mit exit(); abbrechen.

Nun weiter:
Wenn du die Methode outputCaptcha aus der Klasse Captcha vererben willst, muss du sie auf protected setzen, weil die Child-Klasse sonst keinen Zugriff hat.
Ob die Vererbung hier so sinnvoll ist, ist eine andere Frage. Du könntest auch einfach innerhalb der Klasse Kontaktformular ein Captcha-Objekt erstellen.
Ich hab jetzt einfach mal ohne Vererbung und mit Output Buffering so den groben Aufbau geschrieben:
[php]

<?php class captcha { // ------------------------------------------------- public function __constructor () { if ( isset($_GET['gen']) ) $this->genCaptcha(); else $this->outputCaptcha(); } // ------------------------------------------------- private function genCaptcha () { // Session-Variable setzen // header: png/image // Bild generieren mit imagettf etc. aber vor allem direktem Output // exit } // ------------------------------------------------- private function outputCaptcha () { // tag mit href auf selbe datei aber ?gen // } // ------------------------------------------------- public function check () { return ( $_SESSION['var'] == $_POST['input-var'] ); } } class Kontaktformular { private $mailto = "me@example.org"; private $b_captcha = true; private $c; // ------------------------------------------------- public function __constructor($mailto, $b_captcha) { $this->mailto = $mailto; $this->b_captcha = $b_captcha if ( $_POST ) $this->checkPost(); $this->outputForm($mailto, $b_captcha); // sieht unsinnig aus, ich weiß } // ------------------------------------------------- private function outputForm ($mailto, $b_captcha) { // , , etc. if ($b_captcha) { $this->c = new captcha; } // submit, } // ------------------------------------------------- private function checkPost() { // Eingabe überprüfen bla bla if ( ... AND $this->c->check() ) { $this->mail(); // Output: "Email versendet." } else // Fehlendes Zeug anzeigen. } // ------------------------------------------------- private function mail() { // mail an $this->mailto mit Inhalt aus $_POST } } ?>[/php]

Und dann mit new Kontaktformular(„mailadresse“, true); aufrufen

Grüße
Voodoo

Dankeschön!
Jetzt versteh ich nur noch eines nicht so richtig
[PHP]
private function outputForm ($mailto, $b_captcha)
{
// , , etc.
if ($b_captcha) {
$this->c = new captcha;
}
// submit,
}
[/PHP]

Hier muss ich einfach echo „“; machen und später wenn ich new Kontaktformular(„mailadresse“, true); mache erscheint das Komplette Formular?
Und der __constructor steuert sozusagen den Ablauf?

Noch mals Vielen Dank für deinen Aufwand!

Richtig, der Konstruktor, sagt den Methoden, ob sie was machen müssen.

Naja, da fehlen natürlich sämtliche input-Elemente, also quasi das Formular als solches. Aber das kannst du ja mit ner Schleife oder so ausgeben.

Also, wenn du mit echo arbeiten willst, musst du die captcha-Klasse in eine andere Datei packen (im Beispiel im selben Verzeichnis, wie die Hauptdatei.

captcha.php:

[php]class captcha {
// -------------------------------------------------
public function __constructor ()
{
if ( isset($_GET[‚gen‘]) )
$this->genCaptcha();
else
$this->outputCaptcha();
}

// -------------------------------------------------
private function genCaptcha ()
{
// Session-Variable setzen
// header: png/image
// Bild generieren mit imagettf etc. aber vor allem direktem Output
// exit
}

// -------------------------------------------------
private function outputCaptcha ()
{
// tag mit href auf captcha.php?gen
//
}

// -------------------------------------------------
public function check ()
{
return ( $_SESSION[‚var‘] == $_POST[‚input-var‘] );
}
}[/php]andere Datei:
[php]class Kontaktformular {

private $mailto = "me@example.org";
private $b_captcha = true;
private $fields = array("author" => array("Dein Name", true, "text"),
                        "email" => array("Email-Adresse", true, "text") );
private $c;

// -------------------------------------------------
public function __constructor($mailto, $b_captcha, $fields)
{
$this->mailto = $mailto;
$this->b_captcha = $b_captcha
$this->fields = $fields; siehe Oben

    if ( $_POST )
        $this->checkPost();

    $this->outputForm($mailto, $b_captcha);            // sieht unsinnig aus, ich weiß
}

// -------------------------------------------------
private function outputForm ()
{
//
foreach ( $this->fields as $k => $v ) {
printf(„%s“,
$v[0],
($v[1])?‚required‘:‚‘,
$v[2],
$_POST[$k],
$k
);
}

    if ($this->b_captcha) {
        include("captcha.php");                        // schöner wäre es mit __autoload()
        $this->c = new captcha;
    }
    // submit, </form>
}

// -------------------------------------------------
private function checkPost()
{
// Eingabe überprüfen (einfach wieder das Array durchlaufen)
if ( … AND $this->c->check() ) {
$this->mail();
// Output: „Email versendet.“
} else
// Fehlendes Zeug anzeigen.
}

// -------------------------------------------------
private function mail()
{
// mail an $this->mailto mit Inhalt aus $_POST
}
} [/php]Dann kannst du einfach ein Array an Feldern (aufgebaut wie die Klassenvariable $fields) mitgeben und alles ist gut.

Mhm, also wenn ich erlich bin verstehe ich immer noch nicht so genau wieso ich eine Ausgabe, z.B. einen Text mit einer schleife ausgebn muss.
Ich werde mir das Später noch mal anschauen und zu versuchen das ganze zu verstehen. Jetzt gehe ich erst mal Schlittenfahren, bei uns liegt ja nicht alle Tage Schnee :smiley:
Also vielen Dank :wink:

Naja, das ist ganz einfach:

Es spart Code, und macht es auch flexibler. Du kannst mit der Schleife so viele Felder, wie du möchtest einfügen, indem du einfach nur einen Parameter änderst. Sonst müsstest du immer in der Klasse selbst was ändern.

Und um deine Frage zu beantworten, man benutzt IMMER OOP :wink: :stuck_out_tongue:
alles was man als php programmierer kann sollte man versuchen OO umzusetzen da die handhabung so um ein vielfaches leichter wird.

es mag dir jetzt zwar viel vorkommen für ALLES und JEDEN eine klasse zu schreiben aber hier ein einfaches beispiel.

du willst in deriner datei user.php einen user repräsentieren, dieses kannst du so machen wie du es willst du kannst tausende funktionen in die klasse packen und dieses immer erweitern, die funktionen kannst du dsich gegenseitig aufrufen lassen… alles was du willst aber irgendwann kommt der zeitpunkt da wilslt du was ändern und dann blickst du einfach nicht mehr durch weil du so viele funktionen hast ect…

jetzt stelle dir vor du hättest eins chönes user object von dem du nur eine instanz erzeugen müsstest um es zu laden, wenn es nicht sogar schon geladen ist. außerdem hast du so immer einen anlaufpunkt wenn du etwas haben willst.

[php]class user {
private static $instances;

private function __construct($uID) {
    /$this->// do something
}

public function getInstance($uID) {
    if(!array_key_exists($uID, self::$instances)) {
        self::$instances[$uID] = new self;
    }
    return self::$instances[$uID];
}

/**
 * ...
 */

}

try {
$daten = array();
$user = user::getInstance(1);
$user->getName();
$user->getAge();
$user->getEmail();
$daten = $user->loadData();

/**
 * ...
 */

} catch(UserNotExistsException $e) {
return array(‚error‘ => true, $e->getMessage());
} catch(Exception $e) {
Logger::log($e);
return array(‚error‘ => true, ‚Es ist ein unerwarteter Fehler aufgetreten‘);
}[/php]

das error handling ist so auch viel einfacher und du kannst einfach machen was du willst :smiley:

hoffe auch ich konnte dir wenigstens ein bisschen weiterhelfen ^^

//Edit: mir ist gerade aufgefallen das ich etwas n bissel durcheinander gebracht habe ^^ das ändern einer klasse ist nie erwünscht, außer um bugf zu fixen ^^… wenn eine klasse fertig ist dann sollte sie nie mehr angefasst werden müssen. das heußt das du so programmierst das wenn du jetzt etwas hinzufügen möchtest dann baust du z.b. ein AbstractUserModel und dann kannst du verschiedenne user models erstellen oder so… tob dich einfach n wenig aus ^^

Das heißt egal was ich in PHP mache sollte ich immer in OO umsetzen?
Gut ich glaube erst mal ich versuche mir mal ne gaaaanz kleine Klasse zu erstellen wo einfach Hallo ausgibt^^
Den das mit der Ausgabe habe ich immer noch nicht sooo ganz verstanden.

Mhm, okai cih glaube ich habe da irgendetwas grundlegendes nicht verstanden, denn diese Zeilen werfen ein Fehler auf.

[PHP]

<?php class Ausgabe { private $fields = array("hallo"); public function __counstructor ( $this-> ausgeben(); } public function ausgeben() { foreach ($fields as $key => $value) { echo "$value"; } } ?>

[/PHP]

Fatal error: Cannot re-assign $this in \index.php on line 9

//Edit

[PHP]
Jetzt sind die Fehlermeldungen weg, aber ich seh td kein Hallo

<?php class Ausgabe { private $fields = array("hallo"); public function __construct() { echo $this-> ausgeben(); } public function ausgeben() { foreach ($this-> $fields as $key => $value) { echo "$value"; } } } ?>

[/PHP]

so würde ich es machen ^^

[php]class Ausgabe
{
private $fields = array(„hallo“);

public function __construct(array $ausgabe = array())
{
    if(count($ausgabe) > 0) {
        $this->fields = $ausgabe;
    }
    $this->ausgeben();
}

private function ausgeben()
{
    foreach ($this->fields as $value) {
        echo $value;
    }
}

}

new Ausgabe();[/php]
dir passieren oft fehler das du ein { vergisst oder anstadt ein { ein ( schreibst auf sowas musst du unbedingt achten das sind fehler die eigentlich nicht passieren dürfen… außer wenn man gaaaaaaaaanz lange programmiert oder erst gaaaaaanz wenig programmiert hat ^^ sonst kann man sowas eigentlich selber fixen :wink:

Da hast du recht, dass ist mir auch schon aufgefallen. Muss ich unbedingt mal mehr drauf achten!

Wieso hast du beim Konstruktor deise Zeile eingefügt?
[PHP]
array $ausgabe = array()
[/PHP]

Was bewirkt die?

Das ist ein Standardwert für diesen Parameter. Wird der Parameter nicht übergeben, nimmt die Variable automatisch diesen Wert an.

Aber: Wenn du OOP lernen möchtest, solltest du dir irgendein Beispiel suchen, wo OOP Sinn ergibt. Ich meine… echo „Hallo“;? Für so eine Aufgabe musst du nicht so ein aufwendiges Moddel basteln. Du könntest aber zum Beispiel eine DB-Klasse bauen, oder etwas in der Richtung.

Ich finde das hier ist eigentlich ein ganz brauchbares Tutorial: Peter Kropff - Tutorials - OOP PHP5
Und vor allem auch relativ Praxisbezogen.

damit die klasse wenigstens etwas sinn bekommt ^^ du könntest jetzt schreiben

new Ausgabe(array(
‚hallo‘,
23125,
‚blaaaaaaaaa‘
));

Mhm Ja Relativ^^.
Hab ich gelesen, dass mit Dieter und Dörte hat mich nur verwirrt weil man das nicht wirklich testen konnte.

damit die klasse wenigstens etwas sinn bekommt ^^ du könntest jetzt schreiben

Ok^^, schon verstanden.

Naja gut ich werde jetzte einfach mal was probieren und wenn Fehler auf tauchen kann ihc mich ja wieder melden =)
Es heißt ja immer so schön

„Learning by doing“

=) also noch mal Dankeschön