Baba: PHP: Programmablauf richtig umsetzen

Schönen Abend.

Ich sehe mich vor dem Problem, dass meine php-Programme langsam zu groß werden. Die Ablaufsteuerung (If-Blöcke, Schleifen und Switches) gehen unter zwischen den ganzen Anweisungen (Kopiervorgänge, Tests, Fehlermeldungen, Datenbankschreibereien, etc.). Wie trennt man das schön voneinander. Gerne würde ich das alles Modularisieren. Doch ich weiß nicht recht wie. Ich habe überlegt, eine Klasse zu missbrauchen, weiß aber nicht, ob das das adäquate Mittel ist. Normalerweise benutze ich Klassen für Exemplare irgendeiner Sache (wie User, der dann Methoden hat, wie GetUsername()) oder als Werkzeuge (wie eine Abstraktionsschicht für Sqlite-Datenbanken, die dann Methoden hat wie InsertInto()). Ich weiß einfach gerade nicht, ob man Klassen auch zur Ablaufsteuerung verwenden sollte.

Das andere Problem, neben der Frage, ob es das richtige Mittel ist, sehe ich darin, dass ich dann ziemlich frickeln muss mit Übergabewerten und Rückgabewerten. Beispiel: momentan habe ich im Script 15-20 Dateinamen und Pfade definiert auf die immer wieder zugegriffen wird, es gibt ein XML-Objekt, dass eine Art logging für den gesamten Ablauf mitschneidet, auf das ich nicht verzichten kann.

Die Frage lautet: kann/sollte man eine Klasse zur Ablaufsteuerung verwenden?

Wenn ich jetzt zum Beispiel an das XML-Objekt (logging-Objekt) denke, frage ich mich, wie ich das in jede Methode rein- und wieder rauskriege. Ok, vielleicht so:

class Process{  
  
  public $XML;  
  
  // set or get xml  
  public function XML($xml = null){  
  
    if(is_null($xml)) return $this->XML;  
    else              $this->XML = $xml;  
  
  }  
  
  public function ConnectToDatabaseA($var){  
  
    //## tu et hier und im Fehlerfall:  
    $this->XML->log("connection failed");  
  
  }  
  
  
}  
  
$Process = new Process();  
$Process->XML($_XML);  
$Process->ConnectToDatabaseA("dbxy");  
$Process->CheckIrgendwas("whatever");  
$Process->RechneIrgendwas("dbxy");  
$_XML = $Process->XML();

Aber dann: wie kriege die Programmabläufe umgesetzt? Wenn ConnectToDatabaseA() die Verbindung nicht schafft, etc. Läuft das dann über die returns der einzelnen Methoden?

$Process = new Process();  
$Process->XML($_XML);  
if($Process->ConnectToDatabaseA("dbxy")){  
  if($Process->CheckIrgendwas("whatever")){  
    $Process->RechneIrgendwas("dbxy");  
  }  
}  
$_XML = $Process->XML();

Bislang konnte ich durch ein break; stets raus aus der Kette, ohne jedesmal eine neue If-Ebene einzufügen. Gibt es einen Pauschal-Abbruch für die Prozesskette bei dieser Art Umsetzung? (ohne die und throw new exception)

Bin ich damit komplett auf dem Holzweg? Gibt es vielleicht etwas viel einfacheres zum Umsetzen von Programmabläufen und Modularisieren von Code?

Zwei Dinge noch:

  • der jetztige Code hat 1000 Zeilen und wird jetzt schwer zu warten. Bis 300 Zeilen war das alles noch ok, aber es wird ja immer komplexer.
  • dies ist eine Lernfrage(!). Ich bin mir ganz sicher, dass die Antwort auf der Welt schon jemand gefunden hat. Nur für mich ist das jetzt neu (auf diesem Level).

Cheers,
Baba

  1. Om nah hoo pez nyeetz, Baba!

    Bin ich damit komplett auf dem Holzweg? Gibt es vielleicht etwas viel einfacheres zum Umsetzen von Programmabläufen und Modularisieren von Code?

    include? Einfacher auf jeden Fall, ob es aber auch den Paradigmen entspricht, weiß ich nicht.

    Matthias

    --
    1/z ist kein Blatt Papier.

    1. include?

      Kurz auch dran gedacht.
      Der größte Nachteil: Für jedes bisschen Code *eine neue Datei*.
      Und: da der Gültigkeitsbereich der Variablen dann trotzdem über alle Dateien geht: viel Spass beim Fehler finden.
      Mir fallen noch mehr ein...

      Cheers,
      Baba

  2. Hallo!

    Die Frage lautet: kann/sollte man eine Klasse zur Ablaufsteuerung verwenden?

    Das ist bei dem MVC-Modell gängige Praxis. Wieso solltest du das nicht tun?

    Wenn ich jetzt zum Beispiel an das XML-Objekt (logging-Objekt) denke, frage ich mich, wie ich das in jede Methode rein- und wieder rauskriege.

    Wie wäre es mit __autoload()?

    Grüße, Matze

    1. Das ist bei dem MVC-Modell gängige Praxis. Wieso solltest du das nicht tun?

      Vielleicht nur, weil ich es noch nicht gesehen habe  :) Hast Du noch einen *guten* Link für MVC und php?

      Wenn ich jetzt zum Beispiel an das XML-Objekt (logging-Objekt) denke, frage ich mich, wie ich das in jede Methode rein- und wieder rauskriege.
      Wie wäre es mit __autoload()?

      Was hat __autoload damit zu tun? Soweit ich das verstanden habe bedeutet das nur, dass das script erst included wird, wenn die Klasse instanziert wird. Ein Mechanismus zum Schonen von auf Ressourcen?! Ich habe das Problem, dass ich $_XML draußen (ausserhalb der Klasse) habe, bearbeiten will (innerhalb der Klasse) und wieder draußen benötige. Was hat das mit autoload zu tun?

      Cheers,
      Baba

      1. Tach!

        Hast Du noch einen *guten* Link für MVC und php?

        Alle bedeutenden Frameworks verwenden MVC - sag ich jetzt mal so, ohne sie alle zu kennen. Schau dir mal das Zend Framework an.

        dedlfix.

      2. Hallo!

        Was hat __autoload damit zu tun? Soweit ich das verstanden habe bedeutet das nur, dass das script erst included wird, wenn die Klasse instanziert wird. Ein Mechanismus zum Schonen von auf Ressourcen?! Ich habe das Problem, dass ich $_XML draußen (ausserhalb der Klasse) habe, bearbeiten will (innerhalb der Klasse) und wieder draußen benötige. Was hat das mit autoload zu tun?

        Das XML-Objekt ist kann von überall aus angesprochen werden ohne, dass du die Datei explizit includen musst. Ich habe mich bei dem Hinweis von deiner Aussage

        Beispiel: momentan habe ich im Script 15-20 Dateinamen und Pfade definiert auf die immer wieder zugegriffen wird[..]

        irritieren lassen. Ich dachte die Dateinamen und Pfade beziehen sich auf weitere Klassen.
        Der Vorteil ist, dass du damit wesentlich flexibler bist. Du brauchst dir nur Gedanken darüber machen wo du die Klassen ablegst und nicht darum sie zu includen. Ressourcen sparst du ein falls die benötigte Klasse, z.B. das XML-Objekt, nicht immer instanziert, also auch nicht includiert werden muss weil das Script sie a) nicht zwangsläufig benötigt wird (z.B. nur in bestimmten Fällen, abhängig vom Verhalten der instanzierenden Klassen) oder b) der Ablauf des Script vorher abgebrochen wird (z.B. bei einem Fehler).

        Allgemein ist es von Vorteil so ziemlich alles in Klassen zu verpacken und diese entsprechend dem MVC-Modell zu strukturieren. Das heißt z.B., dass Controller-Klassen keinen Zugriff auf das Dateisystem oder die Datenbank haben, Modell-Klassen allerdings schon. Ausnahmen bestätigen die Regel. Vorschläge, Tutorials etc. dazu gibt es tonnenweise im Internet. Es wäre müßig jetzt ein bestimmtes dazu vorzuschlagen. Ein erster Anlaufpunkt könnte aber Wikipedia sein wenn du so gar keine Ahnung hast wie das umzusetzen ist. Anschließend kannst du gezielter die Suchmaschine deines Vertrauens zu Rat ziehen oder dir, wie schon vorgeschlagen, eines der bekannteren Frameworks anschauen.

        Grüße, Matze

  3. Hallo

    Bin ich damit komplett auf dem Holzweg? Gibt es vielleicht etwas viel einfacheres zum Umsetzen von Programmabläufen und Modularisieren von Code?

    nutze Controller-Klassen. Diese steuern den Programmablauf.
    Werte übergibst du an die Klasse, am besten nutze Dependency Incjection

    http://www.potstuck.com/2009/01/08/php-dependency-injection/

    Zwei Dinge noch:

    • der jetztige Code hat 1000 Zeilen und wird jetzt schwer zu warten. Bis 300 Zeilen war das alles noch ok, aber es wird ja immer komplexer.

    1000 Zeilen für eine Datei finde ich sehr viel zu lang. Lagere alles in Klassen aus, nutze Kontroller-Klassen für Teilabschnitte.

    1. Hallo
      nutze Controller-Klassen. Diese steuern den Programmablauf.
      Werte übergibst du an die Klasse, am besten nutze Dependency Incjection
      http://www.potstuck.com/2009/01/08/php-dependency-injection/

      Super Link. Sehe die Vorteile deutlich. Genau so eine dependency ist mein XML-Objekt und in meinem zweiten Beispiel habe ich so eine setterInjection gemacht. Funny, was man alles so macht, ohne die Fachbegriffe zu kennen :) Ich werde das jetzt auf jeden Fall mittels Container realisieren.

      Ganz klar ist mir noch nicht, wie so eine controller-class idealerweise designt ist. Ich denke, ich werde einfach mal mein bisheriges Script als Klasse umsetzen und sehen, ob es mich unterstützt beim Entwickeln. Vielleicht klären sich diese Fragen ja noch von alleine. Vielleicht mache ich aber auch wieder irgendwelche Kardinalfehler. Gibt es noch irgendwelche *guten* Links und Beispiele? Google gibt mir grad nicht viel (z.b.).

      Auch weiß ich noch nicht wie ich das Terminieren schön umsetze (eheml. break;).

      Cheers,
      Baba

  4. Tach!

    Gibt es vielleicht etwas viel einfacheres zum Umsetzen von Programmabläufen und Modularisieren von Code?

    In der Regel gibt es keine einfachen Lösungen für komplexe Probleme. Du kannst nur versuchen, die Komplexität so auf das Gesamtsystem zu verteilen, dass die Einzelteile einfach und damit verständlich und wartbar bleiben. Es gibt da ein Openbook aus dem Galileo-Verlag: Objektorientierte Programmierung. Das zeigt dir eine ganze Menge Muster und Prinzipien, die man verwenden beziehungsweise an denen man sich orientieren kann.

    dedlfix.