Andreas Korthaus: Modulares Programmieren mit PHP

Beitrag lesen

Hallo!

weil mir solangsam der Schädel platzt, muss ich nun einfach mal in die Runde frage und ein paar Anregungen und Meinungen einholen.

Ich sitze zur Zeit an ähnlichen Problemen, und hatte dazu vor einigen Tagen einen recht fruchtbaren Thread gestartet: http://forum.de.selfhtml.org/archiv/2002/12/31778/

Diese Klassen sollen nun erstmal so weit wie möglich eigenständige Module sein, die zwar teilweise auf andere Klassen angewiesen sind, aber soweit möglich auch ohne diese auskommen.

Aber meiner Meinung nach ist die Modularität das genaue Gegenteil. Ein Modul soll ganz klar definierte Schnittstellen haben. Das Modul soll sich nicht alles möglicsh alleien beschaffen, sondern sich alle Daten aus anderen Modulen hoolen, oder die Daten sollen von anderen Modulen übergeben werden. Die Schnittstelel bleibt dann immer gleich, und Du kannst um das Modul selbstverändern, ohne das das Auswirkungen auf andere Teile des Programms hat. Umgekehrt kannst Du einfach die Umgebung verändern, z.B. von MySQL auf postgreSQL, wofür Du nur das DB-Modul anpassen mußt, aber keines der anderen Module, da die alle nur über das DB-Modul mit der Datenbank kommunizieren.

ein beispiel, es gibt eine fileUpload-Klasse, die hat die Aufgabe eine Datei die per POST hochgeladen wurde in ein bestimmtes Verzeichnis zu verschieben. Nun gibts verschiedene Filter und Regeln, die man definieren kann um zu entscheide wird die Datei akzeptiert oder nicht.
So weit so gut, nun hab ich entschieden diese um eine Klasse errorReporting zu erweitern, welche Fehlermeldungen und Ereignismeldungen verwaltet. Weiter gibts eine Klasse die Beispielsweise Thumbgrafiken erzeugen kann.

Meine erste Idee war folgende. Die errorReporting-Klasse als Basisklasse fast aller Klassen zu verwenden, da Fehler überall auftreten können, die thumbnails selbst sind hingegen nicht so elementar für meine fileUpload-Klasse, deswegen erzeuge ich nach Bedarf eine Instanz davon.

Die Idee halte ich nicht für gut. Die Error-Klasse sollte ein eigenes Modul sein, welches Du in den anderen Modulen verwenden kannst, oder auch nicht. Ich würde z.B. ein Upload-Modul schreiben, darin steht eien Klasse, der bei einem Uplaod die Daten übergeben werden, also Temp-Name, Name, gewünschter Speicherpfad, gewünschter Name, zu erwartender Typ(z.B. Bild)...
Diese Klasse hat dann auch eine Mothode checkFile().
Bevor die Datei gespeichert wird, wird mit checkFile("Bild") geprüft, ob es sich bei der temporären Datei tatsächlich z.B. um eine gültige Bild-Datei handelt. Wenn dem so ist dann kannst Du die Datei kopieren, umbenennen...
Wenn dem nicht so ist, dann rufst Du das Error-Modul auf, welches eine Fehlermeldung produziert und/oder loggt.

Ich würde in das Modul vielleicht auch für jeden Typ eine extra Methode schreiben, ich habe z.B. auch Excel-Dateien, das würde ich ganz anders prüfen als eine JPG-Datei.

class fileUpload extends errorReporting {

function createThumb() {
    $this->createThumb = new thumbnail();
    ....
  }

Wie gesagt, ich würde das anders machen, da das so auch unlogisch ist, und Module sollen ja logisch sein. Was hat das kopieren von Bildern in einem Error-Modul verloren?

Nun ist aber eigentlich auch so, das ja meine fileUpload-Klasse selbst nicht wirklich davon abhängig ist Fehlermeldungen speichern zu können. So mache ich sie jedoch abhängig davon. Wäre es vielleicht nicht sinnvoller auch die errorReporting-Klasse nur bei Bedarf zu Instanzieren?

Ja, da hänge ich auch noch irgendwie. Insgesamt sollte man IMHO nur die Module laden die man auch braucht - nur wie? Dafür braucht man dann wohl das Basismodul, welches immer geladen wird, also in alle Scripte per include() eingebunden wird, und welches dann entscheiden muß, welche Module geladen werden sollen. Nur in welcher Form soll man das steuern? Sicher müssen dann die Modul-Dateien mit include eingebunden werden, udn mit IFs kann man das ja auch prima steuern, nur woher bekommen die if-Bedingungen wiederum ihre Daten? Wenn ich jetzt z.B. einen File-Upload mache. Dann habe ich das HTML-Forumlar, welches per POST am besten an sich selbst geschickt wird. Woher weiß jetzt das Basis-Modul, das an dieser Stelle das File-Upload Modul benötigt wird? Bisher mache ich sowas(ohne Module) immer so, dass ich frage

if($_POST['submit']) {
  // file upload CODE
}

Aber wie mache ich das jetzt mit dem Basis-Modul? Das kann iach mir nicht vorstellen. Vielleicht frage ich _jedesmal_ (duch einbinden der Basis-Klasse in alle Scripte) mit if($_FILE) und wenn das TRUE ist dann  binde ich halt die file-upload Klasse ein. Aber das müßteman dann ja mit jedem einzelnen Modul machen. Gibt es da keine bessere Lösung?
Und nochwas, wann sollte man eine Klasse instanzieren? Am besten doch schon im Basis-Modul, nach dem Include, dann ein "$file = new fileUpload", nur dann hätte ich im Basismodul eine Variable definiert, die ich ja im Prinzip im uplaod-Modul wissen müßte, das ist ja wieder blöd. Also sollte das Uplaod modul aus der Klasse bestehen, und aus PHP-Anfweinungn die eine Instanz erstellen, und der Klasse dann die notwendigen Daten übergeben. Nur dann ist das mOdul ja wieder nicht so besonders modular, dann greife ich im Modul ja wieder direkt auf Umgebungsvariablen zu... wie macht man das denn besser?
Man bräuchte noch eine Möglichkeit, diesen Teil auch abzukapseln, also der Upload-Klasse über deren Schnittstelle die Daten zu übergeben. Aber wie?

Macht es Sinn in der Praxis, alle Klassen die man zwar brauchen könnte, jedoch nicht unbedingt benötigt in einer Klasse bei Bedarf zu Instanzieren? So überlegt könnte ich ja eigentlich fast alles so handhaben, da beinahe jede Klasse bis zu einem gewissen Punkt alleine klar kommt. Oder leidet die übersichtlichkeit und Transparenz irgendwann darunter?

Das würde ich sowieso machen, das wäre ja ein tierischer Overhead wenn man immer alles laden würde, nur wie man das in der Praxis mit PHP sauber macht ist mir nicht nicht wirklich klar. Oder könnte hier "::" helfen, also Methoden nutzen ohne Instanz?

Ich mache mir gerade megaviele Gedanken, wie ich Klassen so gestalten kann, die sie so eigentständig wie möglich funktionieren und welche Aufbau wirklich sinn macht. Vielleicht kann jemanden ein paar Tipps geben, der sich schon intensiver damit auseinandergesetzt hat, oder kennt ein Tutorial das nicht auf Einsteigerniveau liegt, davon gibts genug.

Das ist schwer, ich komme da auch nur schleppend weiter, das hört sich immer so klar und logisch an, was die Christians oder Sven zu dem Thema sagen, nur wenn ich danach da sitze und das umsetzen will stehe ich da und weiß nicht wo und wie ich ansetzen soll. Theoretisch habe ich es denke ich langsam verstanden, jetzt muß ich das nur noch in der Praxis umsetzen können, was nicht ganz so einfach ist. Was ich so langsam raushabe ist zumindest das DB-Modul und das Ausgabe Modul, hierfür bin ich dabei Smarty etwas zu erweiter, das ich hier auch mehrsprachige Templates einsetzen kann, und zwar der Art, dass ich nur je ein Template habe, und das Smarty für jede Sprache ein "kompiliertes" Template speichert, kompiliert heißt in diesem Zusammenhang das Script und das Template schon zusammensetzt damit das nicht bei jedem Seiten aufrufe immer wieder gemacht werden muß. Nur muß ich hierzu die Smarty-Klasse abändern, bzw. erweitern.

Grüße
Andreas