[PHP] Gelaber über Klassen

Chris Hunter
Klassen, warum zum teufel benutz jemand Klassen?

Also zum ersten fällt mir ein recht triftiger grund ein, warum man Klassen benutzt. Und dieser grund ist die wiederverwendbarkeit. Ihr kennst das bestimmt alle. Einige Dinge programmiert ihr immer und immer wieder. Z.B. eine Routine/Funktion die zur datenbank verbindet, diese weider schließt oder einträge macht. Warum sollte man diesen code nicht so gestalten, das man ihn immer und immer wieder verwenden kann, ohne ihn jedes mal neu zu schreiben? oder man findet in irgendeinem forum einen armen hansel der gerade so etwas braucht? für solch einen Zweck, eben einen wiedferverwendbaren, gekapselten code, oder ein sog. Klassenmodul (*g*) bietet sich die klasse an.

die klasse ist ein unabhängiges, in sich gekapseltes stückchen funktionalität, die sich meistens sehr schnell in ein bereits vorhandenes projekt einbinden lässt. die klasse ist so definiert, das sie vergleichsweise störungsfrei in ein existierendes Projekt eingesetzt werden kann, ohne gefahr zu laufen, mit bereits benutzten funktions- und variablennamen zu kollidieren.



Wie definiere ich eine klasse, oder wie erzeuge ich ein Objekt?

Also nehmen mir einmal das beispiel was ich bereits oben angesprochen habe, und wir brauchen eine klasse, die zu einer datenbank verbindet.
angenommen, es ist eine Reihe von Funktionen für diesen zweck vorhanden, und diese Funktionen sollen in eine Klasse umgewandelt werden:


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
$Link_ID  = 0;  // ID der aktuellen DB-Verbindung
$Query_ID = 0; // ID des aktuellen Abfrageresultates
$Error    = 0;    // Letzte Datenbank-Fehlermeldung

function connect() { ... }
function query()   { ... }
function next_record() { ... }
function num_rows() { ... }


aus diesen Variablen und Funktionen wird eine Klasse, indem man vor alle verwendeten variablen das Schlüsselwort var schreibt und indem man alle Variablen und Funktionen mit einem class-Konstrukt umschließt. damit ist dieser codeteil auch vom rest des scripts gekapselt, bzw getrennt. halt ne klasse, ne. das ganze sieht dann als klasse z.b. so aus:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
class DB_MiniSQL 
{

 var $Link_ID  = 0; // ID der aktuellen DB-Verbindung
 var $Query_ID = 0; // ID des aktuellen Abfrageresultates
 var $Error    = 0; // Letzte Datenbank-Fehlermeldung

 function connect() { ... }

 function query()   { ... }

 function next_record() { ... }

 function num_rows() { ... }

}


da wo {...} stehst ist nactürlich der inhalt der funktion einzutragen, so ganz automatisch gehts nicht smile
so langsam sollte das prinzip der klasse aber klar werden. und auch die macht oder die absicht zu erkennen sein, die hinter der klasse steht.
gut, ähhh. grübeln.... ja. genau. erzeugen von objekten.
dazu sollte man noch etwas wissen. eine klasse so wie sie da oben steht ist noch kein funtionierendes script. eigentlich ist es nichts weiter als ein bauplan zu einer funktionstüchtigen einrichtung. man kann also mit einer classe alleine nicht viel anfangen. ganausowenig wie man in einer blaupause einer wohnung wohnen kann. dazu muss man erst noch das haus bauen, bzw. ein objekt erzeugen. in deisem fall ist es ein object der klasse, oder des klassenbauplans DB_MiniSQL. und das geht so:

code:
1:
2:
3:
4:
$db1 = new DB_MiniSQL; // $db1 ist ein objekt der classe DB_MiniSQL
$db2 = new DB_MiniSQL; // $db2 ist noch ein objekt derselben klasse


man sieht schon, wie schön wiederverwendbar eine klasse ist. diesmal in einem script, einem project.
so, jetzt schaun wir mal weiter:

das objekt $db1 der klasse kann man sich wie ein array mit einer besonderen syntax vorstellen.
Aber anstatt auf
$db1["Link_ID"] und
$db1["Error"] zuzugreifen, muß man
$db1->Link_ID und
$db1->Error verwenden.

achtet aber darauf, dass es NICHT heißt:
$db1->$Link_ID oder
$db1->$Error
das $ für die variabeln kommt immer vor das object, nicht an das element.

das waren die variabeln, die in der klasse definiert wurden. ihr erinnert euch? ein bischen weiter oben...



Auch die Funktionen in einem objekt einer klasse lassen sich so aufrufen:
$db1->connect()
$db1->query()
und so weiter....
....und so fort...
natürlich auch vom zweiten erzeugten object $db2:
$db2->connect()
$db2->query()

selbe mache...
..ist halt günstig, wenn ihr in einem script zwei db-connect machen müsst. ne klasse erspaart manchmal einiges an arbeit.


gut, was könnte man jetzt noch erklären in zusammenhang mit klassen. mmhh.. grübeln again...
ja genau vieleicht noch ganz interessant und wichtig ist das $this...





Was ist das $this? Und was mache ich damit?

innerhalb einer Funktion, z.b. wie oben schon angefangen die connect() funktion, muß auf die Variable Link_ID zugegriffen werden, um das Resultat eines Connect abzuspeichern. In connect() können wir nicht wissen, wie die Funktion nun gerade heißt, also ob ihr Name nun gerade $db1->connect() oder
$db2->connect() oder
$tausenhussassa->connect()

ist und ob die Link-ID nun in
$db1->Link_ID oder in
$db2->Link_ID
abgespeichert werden muß.

Eigentlich ist das auch egal: Wir wollen ja nur auf unsere eigene Link-ID zugreifen. also genau die link ID des objects. das gerade am werkeln ist.
$this bezeichnet nun genau unser eigenes Objekt. genau das object, das gerade angesprochen ist. im code der klasse sieht das dan ungefähr so aus:


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
class DB_MiniSQL {
  var $Link_ID = 0;

  function connect() {
    $this->Link_ID = mysql_connect(...);
    ...
  }

...andere funktionen...
}





...mhhh... den kontruktor einer klasse kann ich auch noch erklären um das ganze dann fast abzuschließen:


was ist der konstruktor, und wofür ist er gut?


Der kontruktor einer klasse ist soetwas wie eine initialisierung. ein setup. oder ja genau. das ist er. eine initialisierung.

dabei ist ein kontruktor nichts anderes als eine normale funktion innerhalb einer klasse. sie unterscheidet sich von anderen funktionen derselben Klasse nur dadurch, daß sie beim erzeugen der klasse, oder des klassenobjects mit new automatisch aufgerufen wird. also jedesmal wenn ihr

$db1 = new DB_MiniSQL;

schreibt, wird der konstruktor automatisch aufgerufen. ihr müsst also nicht jedesmal

$db1 = new DB_MiniSQL;
$db1->setup()

schreiben. ist praktisch, was? na ja ganz so praktisch isses natürlich nicht, denn ein kontruktor aufruf geht sicherlich nicht $db1->setup(). bei kontruktoren ist es in PHP nämlich so, das der kontruktor genauso heißen muss, wie die klasse selbst. in unserem fall der klasse DB_MiniSQL muss der konstruktor also auch DB_MiniSQL heißen...
...jaaaa, das ist ganz wichtig, sonst funztz es nämlich nicht!! eine klasse mit contructor sieht z.b. so aus:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:

class Beispiel {
  
  //KONTRUKTOR
  function Beispiel() {   // wird automatisch aufgerufen
    $this->setup();
  }

  function setup() {  // Initialisierung...
    reset($this->map);
    while(...) {
      ...bla sülz irgendein code...;
    }
  }
}





es gibt noch so einiges anderes was man über funktionen schreiben könnte, aber ich will mich hier nicht unendlich auslassen. wen es interessiert kann mich ja noch wieter fragen.

ich könnte noch ein bischen über vererbung schreiben oder metainfos einer klasse, oder wie man klassden in einer session speichern kann..

..wens interessiert...

greets euer Hunter
MMB
Beim Konsturktor kannst du dir Varialben übergeben lassen, die erforderlich für die Klasse sind. Bei einer db-class wär das zB die Verbindungsdaten.
Der große Vorteil des OOP ist, dass man die Sachen besser öfter (bei mehreren Projekten) benutzen kann, als das bei Functionen der Fall ist.
Chris Hunter
ja. das hatte ich ja ganz zuerst geschrieben. zweck der klasse ist halt die wiederverwendbarkeit, bzw. das modulkonzept
Andun
ok

Was ich aber noch gerne wüste st wie ich das dann mit den 2 verbindungen machen muss?

ist dass dann
code:
1:
2:
3:
$db1->connect($verbindungsvars1, . . .)


und

code:
1:
2:
3:
$db2->connect($verbindungsvars2, . . . )


oder wie krieg ich da dann wieder die individualität rein?
Chris Hunter
ja, jedes objekt steht für sich selber.
du kannst quasi mit dieser klasse ewig viele verbindungen herstellen. jedes object bearbeitet und verwaltet dann eine verbindung. und so wie dus machst hastes schon richtig erkannt.

$db1->connect(IP_für_verbindung_zur_db1, passwort_für_db1, ect....)

verbindet dann zur 1. datenbank

$db1->connect(IP_für_verbindung_zur_db2, passwort_für_db2, ect....)

verbindet zur zweiten, und so weiter. querys für die erste verbindung machste dann über

$result = $db1->query("...")

usw...
Andun
gut, das werd ich dann mal bei meinem "prohjekt"einbauen.
Hanfling
Zitat:
Original von Andun
gut, das werd ich dann mal bei meinem "prohjekt"einbauen.


Ich finde bei MySQL lohnt sich nicht wirklich eine Klasse dafür, man sollte verwenden was man braucht, nicht was man kann.

Zudem ist damit so Kram wie, entweder Tabelle ausgeben, falls keine Daten drin sind, Meldung ausgeben, das die Tabelle leer ist, nur mit 2 Datenbankanfragen zu lösen, anstatt einer.

Nebenbei bemerkt, ich war einige Zeit auch dabei, möglichst viel in Klassen zu packen, nur finde ich es macht nur bei wenigen Sachen Sinn. In PHP finde ich zudem, das man hier eigentlich nie Klassen braucht, bzw. sie einem einen Vorteil der Zeitgewinnung bringen. Wenn man etwas wiederverwenden will, kann man auch functions verwenden.
Andun
Also ich hab jetzt mal ne Klasse verwendet bei Votes. Da hab ich nämlich ne menge zu tun.

1. Daten holen
2. Sortieren
3. Auswerten
4. Ausgeben

Das hab ich in ne Klasse geschrieben
MMB
Zitat:
Original von Hanfling
Ich finde bei MySQL lohnt sich nicht wirklich eine Klasse dafür, man sollte verwenden was man braucht, nicht was man kann.
Doch grade dafür ist es sinnvoll. Ein kleines Bespiel. Du hast ne Mysql-Klasse, benutzt sie in einer Funktion, brauchst dann nicht die connection-id per global einbinden und nicht bei jeder query mit übergen und, wenn du eine Fehlermeldung haben willst, brauchst du das nicht hinter jede Query schreiben. Das ist nur ein kleines Beispiel, wo du mit einer Klasse 10x besser dran bist.
Chris Hunter
ja, das posting von hanfling beweist eindeutig, dass er den anwendungszweck einer klasse nicht im geringsten verstanden hat. du kannst mit klassen weit mehr machen als mit einfachen funktionen. und ein sehr großer vorteil der klasse ist die kapselung also die modularität der klasse.

außerdem ist es sehr von vorteil in gewissen bereichen mit objekten zu arbeiten.
von klassen kannst du mehrere instanzen initieren, das ist viel übersichtlicher als beispielsweise jede menge arrays einzuführen.

zudem kannst du mit klassen dinge mit einander verbinden die einfach zusammengehören.

du weist auf anhieb zu welchen vorgang welche funktion gehört.

du kannst dir zwei lager bauen eins für bmw wagen und eins für mercedes. und du weist sofort welche schraube zu welchem wagen gehört.

oder du baust dir ein lager und schmeist einfach alle schrauben in eine kiste.
viel spass beim suchen und identifizieren großes Grinsen
MMB
Den verlgiech mit den Schrauben finde ich gut, damit kann man gut für OOP argumentieren, aber wenn man sich das genau anguckt ist das viel mehr. Vorallem auch die Vererbung.
Chris Hunter
ja genau.

die vererbung macht es möglich in beiden lagerhäusern ruck zuck noch ne kinste mit muttern hinzuzustellen. wärend der hanfling dann einfach die muttern in die schraubenkiste kippt großes Grinsen
Hanfling
Zitat:
Original von Chris Hunter
ja, das posting von hanfling beweist eindeutig, dass er den anwendungszweck einer klasse nicht im geringsten verstanden hat. du kannst mit klassen weit mehr machen als mit einfachen funktionen. und ein sehr großer vorteil der klasse ist die kapselung also die modularität der klasse.

Danke. Glaub mir ich habe den Sinn und Zweck von Klassen verstanden, nur auch das Prinzip des Benutzens von nur dem was man braucht. Ich habe früher auch fast alles in Klassen geschrieben, was irgendwie Sinn machte, aber es lohnt sich halt nicht so oft wie man denkt.
MMB
Es gibt einstazgebiete, da ist man mit Klassen viel besser dran und Klassen kann man besser als Funktionen weiter geben. Was meinst du, wieviele fertige Klassen es gibt.
Chris Hunter
ja genau. das war auch einer der hauptgründe für de OOP - die modularität
Hanfling
Zitat:
Original von MMB
Es gibt einstazgebiete, da ist man mit Klassen viel besser dran..

Die liegen aber weniger bei Projekten mit PHP.
Zitat:
und Klassen kann man besser als Funktionen weiter geben.

Wieso?

Außerdem kommt mal wieder runter, ich habe bloß gesagt das sie bei PHP selten Sinn macht und nicht das man sie nicht verwenden soll. Und die Hauptanwendungen von PHP sind nunmal simple Homepages oder Gästebücher, wo sich Klassen einfach nicht lohnen für MySQL. Außerdem braucht ihr mir nicht die grobe Theorie vorkauen, ich benutz Klassen schließlich nicht seit einer Woche, sondern Ewigkeiten.
Chris Hunter
also ich sag jetzt nichts mehr dazu
MMB
Zitat:
Original von Hanfling
die Hauptanwendungen von PHP sind nunmal simple Homepages oder Gästebücher, wo sich Klassen einfach nicht lohnen für MySQL
Das stimmt nicht, du kannst auch online Shops und umfangreichere Scripts bastlen, wo du dann vorallem Klassen benötigist, aber mir dir macht es keine Sinn zu diskutieren, guck mal oben, was ich zu MySQL-Klasse gesagt hab.
Hanfling
Zitat:
Original von MMB
Zitat:
Original von Hanfling
die Hauptanwendungen von PHP sind nunmal simple Homepages oder Gästebücher, wo sich Klassen einfach nicht lohnen für MySQL
Das stimmt nicht, du kannst auch online Shops und umfangreichere Scripts bastlen, wo du dann vorallem Klassen benötigist, aber mir dir macht es keine Sinn zu diskutieren, guck mal oben, was ich zu MySQL-Klasse gesagt hab.

Wenn du nicht mal richtig lesen kannst, macht es wohl in der Tat keinen Sinn. Ich habe da etwas von Hauptanwendungszweck gesagt und nie gesagt, das man sie nie benutzen soll, sondern bloß das sie meistens (wie von mir gesagt Hauptanwendung simple Seiten mit Gästebuch/Newsscript/ua.) keinen Sinn machen.
Und wegen der online Shops.... rate mal warum ich gesagt habe selten, und nicht nie.
Chris Hunter
@MMB: was glaubst du, warum ich gesagt habe ich sage nichts mehr dazu. jedes wort ist zu viel. weils nicht verstanden wird.

hihihi