Dennis1234: Konzeptionelles zu Funktionen

Hallo liebe Leute,

ich sitze gerade an einem kleinen PHP Projekt, bzw. fange gerade an. Bisher waren die Projekte bei mir eher Spaghetticode. Kapselung von Funktionen fand auf Dateiebene statt. Sprich Datei 1 war der Newsletter, Datei 2 die Kontaktseite. Alle "Funktionen" haben eine Verbindung zu einer Datenbank.

Bei dem neuen Projekt möchte ich eher professioneller vorgehen und Funktions- bzw. Objektorientiert arbeiten. Mein Problem: Ich sehe in der Nutzung von Klassen keinen Sinn. Mir fallen in einem typischen PHP Webumfeld einfach keine Vorteile ein.

Vielleicht kann hier jemand, der bspw. ohne Klassen garnicht leben könnte mal erklären, was daran so toll sein soll (in PHP als Webapplikation).

Ich danke schonmal im Voraus,

Grüße
Dennis

  1. Hallo,

    Vielleicht kann hier jemand, der bspw. ohne Klassen garnicht leben könnte mal erklären, was daran so toll sein soll (in PHP als Webapplikation).

    das Gegeteil werde ich mal tun:
    Es ist absolut egal, ob Du...

      
    class obj{  
       function n1(){  
         $this->wichtig1=1;  
       }  
       function n2(){  
         if($this->wichtig1==1)  
            $this->wichtig2=2;  
       }  
    }
    

    ...notierst, oder so...

      
    function n1(){  
      $wichtig1=1;  
    }  
    function n2(){  
      global $wichtig1;  
      if($wichtig1==1)  
         $wichtig2=2;  
    }
    

    ...vorgehst. Es gibt keinerlei Einsatzgebiete (also nicht nur Webapplikationen), wo auf Objekte nicht verzichtet werden könnte.

    Gruß aus Berlin!
    eddi

    1. Hi,

      OK, dann geb ich dir ein Gegenbeispiel einfachster Art. Du möchtest eine Seite bauen, in der man ein Real-World Objekte bearbeiten kann, sei es Personen, Adressen, ...
      Nach deiner Logik brauchst du ein oder mehrere Seiten, die folgendes machen:

      [...]
      gibBearbeitungsFormularFuerPersonAus(person);
      [...]

      [...]
      gibBearbeitungsFormularFuerAdresseAus(adresse);
      [...]

      Wenn jetzt noch Bankinformationen hinzukommen muss du (1) eine neue Funktion schreiben und (2) diese Seite mit dem Aufruf dieser Funktion erzeugen.

      Nun in objektorientiert:
      Du definiert ein Interface "EditableObject", in dem die Methode "gibBearbeitungsFormularAus" definiert wird. Person, Adresse und Bankinformation sind fortan Objekte und implementieren dieses Interface.
      Deine Seite verändert sich nun ganz einfach zu
      [...]
      myEditableObject.gibBearbeitungsFormularAus();
      [...]
      Neues Objekt? Kein Thema, dieser Code muss nicht mehr angepasst werden.

      MfG
      Rouven

      --
      -------------------
      ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
      1. Moin!

        OK, dann geb ich dir ein Gegenbeispiel einfachster Art. Du möchtest eine Seite bauen, in der man ein Real-World Objekte bearbeiten kann, sei es Personen, Adressen, ...
        Nach deiner Logik brauchst du ein oder mehrere Seiten, die folgendes machen:

        [...]
        gibBearbeitungsFormularFuerPersonAus(person);
        [...]

        [...]
        gibBearbeitungsFormularFuerAdresseAus(adresse);
        [...]

        Warum nicht

        gibBearbeitungsformularAus(dieseperson,formfürperson);
        gibBearbeitungsformularAus(dieseadresse,formfüradresse);

        nehmen?

        Dann kann man in EINER Funktion entsprechend des zweiten Parameters, der den Einsatzzweck signalisiert, passende Ausgaben herstellen.

        Oder man verzichtet direkt auf solchen Overhead und regeln die Bearbeitung von derartigen Daten direkt "OldSchool" durch Ausgabe von Formularfeldern und Entgegennahme von $_POST.

        Wenn jetzt noch Bankinformationen hinzukommen muss du (1) eine neue Funktion schreiben und (2) diese Seite mit dem Aufruf dieser Funktion erzeugen.

        (1) keine neue Funktion, höchstens eine Änderung der bestehenden.
        (2) die Einbindung der Änderbarkeit von Bankinformationen besteht auch bei Objekten.

        Nun in objektorientiert:
        Du definiert ein Interface "EditableObject", in dem die Methode "gibBearbeitungsFormularAus" definiert wird. Person, Adresse und Bankinformation sind fortan Objekte und implementieren dieses Interface.
        Deine Seite verändert sich nun ganz einfach zu
        [...]
        myEditableObject.gibBearbeitungsFormularAus();
        [...]
        Neues Objekt? Kein Thema, dieser Code muss nicht mehr angepasst werden.

        Deine Darstellung hat nicht demonstriert, wo der Vorteil von Objekten liegt. Mir ist jedenfalls kein Vorteil ersichtlich geworden.

        - Sven Rautenberg

        --
        My sssignature, my preciousssss!
        1. Hi,

          das will ich gerade nochmal aufgreifen. Eine andere Frage wäre, wie du ohne einheitliches Interface die Bearbeitung eines bis dato unbekannten Objektes handhabst. Bei uns im Projekt gibt es ein auf dem Java-Modell aufsetzendes Datenmodell, das auch einen Objekt-Editor zum "befüllen" der Objekte umfasst. Da dem Benutzer kaum Grenzen gesetzt sind wie er beispielsweise ein komplexes Objekt zusammensetzt kann die Anwendung auch nicht entscheiden was eine adäquate Darstellung wäre. Es gibt jetzt zwei Möglichkeiten, wie man an die Sache drangehen kann:

          1. Hallo Objekt, gib mir mal deine erste Eigenschaft! Ah, das ist ja ein String, dann zeige ich mal ein Textfeld an. Gut, dann gib mir mal die nächste. Ah, eine Aufzählung, dann sag mir mal alle Werte und ich mache dann eine Dropdown.
          2. Hallo Objekt, zeichne mal bitte {hier} deinen Editor!
            Variante 1 hat ein Problem bzgl. der Wiederverwendung. Wenn du noch eine andere Stelle im Code hast, musst du das ganze nochmal machen. OK, zugegeben, man kann eine Funktion nehmen, das in eine Bibliothek auslagern etc. Ich persönlich bevorzuge aber mittlerweile diesen Grundsatz von "der dem's gehört soll's auch machen".

          MfG
          Rouven

          --
          -------------------
          ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
          1. Moin!

            Eine andere Frage wäre, wie du ohne einheitliches Interface die Bearbeitung eines bis dato unbekannten Objektes handhabst.

            Nun ja, ein "bis dato unbekanntes Objekt" setzt ja voraus, dass es überhaupt ein Objekt gibt. Ohne Objekt (dass man wollen mußte, und ins Leben rufen) kein unbekanntes Objekt. Mag jetzt spitzfindig klingen, aber in PHP im Programmieralltag eines durchschnittlichen Programmierers gibts nur sehr wenig Objekte, dafür aber sehr viele Strings, eventuell einsortiert in Arrays.

            Bei uns im Projekt gibt es ein auf dem Java-Modell aufsetzendes Datenmodell, das auch einen Objekt-Editor zum "befüllen" der Objekte umfasst.

            Wir reden hier im Thread von PHP, nicht von Java. In Java sind viele Dinge komplett anders - beispielsweise weil die Java-Applikation persistent (insbesondere im Hinblick auf die Daten) auf dem Server arbeitet, und durch das Framework die einzelnen Requests vor der Programmlogik gekapselt sind (nehme ich doch mal stark an, dass das so ist).

            Bei PHP läuft das ja komplett anders. Da arbeitet man extrem requestorientiert, d.h. im Sinne einer hohen Performance wird man versuchen, pro Request ausschließlich a) den relevanten Programmcode einzubinden und b) nur die relevanten Daten zu beschaffen und auszugeben, bzw. übermittelte Daten zu verarbeiten und zu speichern.

            Da dem Benutzer kaum Grenzen gesetzt sind wie er beispielsweise ein komplexes Objekt zusammensetzt kann die Anwendung auch nicht entscheiden was eine adäquate Darstellung wäre.

            Der "Benutzer" ist ein Begriff, der zwei Bedeutungen haben kann: Entweder ist es derjenige, der die Webapplikation vor dem Browser bedient - dann muß der nehmen, was programmiert wurde. Oder es ist der gemeint, der ein Framework anwendet und zu einer Applikation zusammenstrickt. Dann hat der natürlich die grundsätzliche Freiheit, abstruse Kombinationen von Daten zusammenzustecken, bzw. das Framework täte gut daran, genau das zu erlauben.

            Es ist aber aus PHP-Sicht ein Vorgang, der ziemlich weit entfernt ist von dem, was man so täglich mit PHP realisiert.

            1. Hallo Objekt, gib mir mal deine erste Eigenschaft! Ah, das ist ja ein String, dann zeige ich mal ein Textfeld an. Gut, dann gib mir mal die nächste. Ah, eine Aufzählung, dann sag mir mal alle Werte und ich mache dann eine Dropdown.
            2. Hallo Objekt, zeichne mal bitte {hier} deinen Editor!
              Variante 1 hat ein Problem bzgl. der Wiederverwendung. Wenn du noch eine andere Stelle im Code hast, musst du das ganze nochmal machen. OK, zugegeben, man kann eine Funktion nehmen, das in eine Bibliothek auslagern etc. Ich persönlich bevorzuge aber mittlerweile diesen Grundsatz von "der dem's gehört soll's auch machen".

            Letztendlich muß alles, was man macht, in HTML ausgegeben werden. Was wiederum bedeutet: Es ist ja nicht damit getan, das Objekt seinen Editor anzeigen zu lassen, sondern Werteveränderungen müssen auch wieder zurück ins Objekt.

            Kann man natürlich als Affenformular realisieren, alle Editoraufrufe von Objekten registrieren ihren Datenbedarf, und je nachdem, ob das Formular neu angefordert oder (geändert) zurückgeschickt wurde, werden die Daten wieder auf die Objekte verteilt. Das ist aber nach meiner Ansicht ein ganz anderer Arbeitsansatz, als er bei PHP üblicherweise, um nicht zu sagen natürlicherweise vorherrscht.

            - Sven Rautenberg

            --
            My sssignature, my preciousssss!
            1. Hello again,

              wobei ASP(.NET) ja im Prinip zumindest im Ansatz diesen Weg geht. Wenn ich ein editierbares Control in meiner Seite platziere, dann ist es weder meine Sache dafür zu sorgen, dass da hinten HTML-Code rauskommt, noch dass die Änderung am anderen Ende von Request zurück in <hier Programmiersprache einsetzen>-Objekt transferiert wird. Das ist alles eine Sache des Controls selber, da es das einzige ist, das weiß, welche HTML-Elemente es an der Client geschickt hat und mit welchen Antworten es möglicherweise rechnen muss.

              Rouven

              --
              -------------------
              ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
              1. Moin!

                wobei ASP(.NET) ja im Prinip zumindest im Ansatz diesen Weg geht. Wenn ich ein editierbares Control in meiner Seite platziere, dann ist es weder meine Sache dafür zu sorgen, dass da hinten HTML-Code rauskommt, noch dass die Änderung am anderen Ende von Request zurück in <hier Programmiersprache einsetzen>-Objekt transferiert wird. Das ist alles eine Sache des Controls selber, da es das einzige ist, das weiß, welche HTML-Elemente es an der Client geschickt hat und mit welchen Antworten es möglicherweise rechnen muss.

                Was aber immer wieder zu (auch hier im Forum dokumentierten) Problemen führt, weil die Programmierer solcher Frameworks allzugerne vergessen, was genau denn da abläuft.

                Probleme gibt es insbesondere dann, wenn das "Control" nicht ausreichend Funktionalität bereitstellt, diese also durch Javascript ergänzt werden muß.

                Oder es wird sowieso standardmäßig die Funktionalität des Controls mit Javascript hergestellt, ohne JS funktioniert's dann aber nicht.

                Ich halte diese Vorgehensweise daher nicht wirklich für den geeigneten Weg, dem Programmierer so viel Arbeit abzunehmen - zumindest, wenn dadurch fragwürdige Methoden eingesetzt werden. :)

                - Sven Rautenberg

                --
                My sssignature, my preciousssss!
      2. Hallo,

        Wenn jetzt noch Bankinformationen hinzukommen muss du (1) eine neue Funktion schreiben und (2) diese Seite mit dem Aufruf dieser Funktion erzeugen. ...
        Du definiert ein Interface "EditableObject", in dem die Methode "gibBearbeitungsFormularAus" definiert wird.

        wie Du selbst schreibst, muß auch für ein Objekt eine Methode geschrieben werden. Punkt Zwei ist gleichfalls kein Argument, weil ich auch ohne Objekt eine Funktion für die Gesamtausgabe schreiben kann.

        Gruß aus Berlin!
        eddi

  2. Guten Tag allerseits,

    |Bisher waren die Projekte bei mir eher Spaghetticode. Kapselung von Funktionen fand auf Dateiebene statt.

    Wieso solltest du das ändern, wenn du bis jetzt damit glücklich warst? Es ist eine reine Glaubensfrage, ob du objektorientiert schreiben möchtest oder nicht. Wenn du - wie du sagst - dir Programme nicht wirklich als Interaktion von Objekten vorstellen kannst, dann lass es!

    Bei dem neuen Projekt möchte ich eher professioneller vorgehen und Funktions- bzw. Objektorientiert arbeiten.

    Objektorientiert = professioneller? Sieht natürlich schöner aus, professioneller ist es deswegen nicht unbedingt. Sonst gäbe es ja wohl keine Profis mehr, die mit PASCAL programmieren. ;)

    Am besten du überlegst dir bei jedem deiner Projekte einzeln, ob sich objektorietierte Programmierung für das Programm eignet oder nicht, statt dich pauschal für eine Variante zu entscheiden. Ich bin zwar bei weitem kein Profi (schon allein alters- und damit erfahrungsbedingt), aber ich mache das so und komme damit sehr gut zurecht.

    Ich hoffe, ich konnte helfen.

    Gruß,
    Der fette Mo

    --
    sh:( fo:| ch:? rl:? br:^ n4:& ie:% mo:) va:) de:> zu:| fl:{ ss:| ls:& js:|
    Der fette Mo is Powered by Jacobs Coffee, System of a down Music and Edelstoff Beer
    1. Kleine Ergänzung:

      Wieso solltest du das ändern, wenn du bis jetzt damit glücklich warst?

      Natürlich vorausgesetzt dass du der Einzige bist, der den Code lesen muss... ;) Sonst solltest du zumindest Funktionen verwenden.

      Gruß,
      Der fette Mo

      --
      sh:( fo:| ch:? rl:? br:^ n4:& ie:% mo:) va:) de:> zu:| fl:{ ss:| ls:& js:|
      Der fette Mo is Powered by Jacobs Coffee, System of a down Music and Edelstoff Beer
  3. echo $begrüßung;

    Ich probier auch mal eine Antwort :-)

    Mein Problem: Ich sehe in der Nutzung von Klassen keinen Sinn. Mir fallen in einem typischen PHP Webumfeld einfach keine Vorteile ein.

    Objekte war unter PHP 4 eine nette Dreingabe, aber ansonsten nicht besonders mit PHP verstrickt. dir war wohl die einzige Klasse, die einem Wald- und Wiesen-PHP-Programmierer gelegentlich über den Weg lief. Und auch diese Begegnung konnte man meiden, gab es doch alle Methoden von dir auch als normale Funktionen.

    Unter PHP 5 wurde das Objekt-Modell verbessert und es gibt ein paar mehr Ansätze, PHP-Funktionalitäten auch oder ausschließlich objektorientiert anzubieten. Beispiele sind SimpleXML, die MySQL Improved Extension (mysqli) und das PHP Data Objects (PDO) interface. Der große Rest ist funktional geblieben. Es gibt beispielsweise keine String-Klasse, die alle String-Funktionen als Methoden anbietet und auch keine ebensolche Array-Klasse. Und das wird auf absehbare Zeit (PHP 6) auch so bleiben.

    Worin liegt der große Vorteil den OOP bietet? Es ist die Kapselung von Daten und Funktionalität zu einer Einheit, sprich: einem Objekt. Und das ist auch in meinen Augen der Hauptvorteil, der sich dem PHP-Programmierer bietet. Diesen Vorteil lernt man dann schätzen, wenn Projekte größer werden. Dann hat man unter Umständen das Problem, die Übersicht zu behalten. Hat man eine Variable an einer Stelle verwendet, ist es ungünstig, wenn man sie an anderer Stelle nochmal verwendet und damit das andere Vorkommen ungewollt beeinflusst. Funktionen zu verwenden ist eine Möglichkeit, den globalen Variablenspeicher zu entlasten.

    Mitunter hat man mehrere Funktionen, die sich mit dem gleichen Thema beschäftigen und gegenseitig Daten benötigen, die aber an anderen Stellen nicht gebraucht werden. Diese Daten liegen dann meist "ungeschützt" global herum. An der Stelle bietet ein Objekt die Möglichkeit, die Daten und Funktionen zusammenzufassen, und das Programm wird wieder etwas aufgeräumter.

    Anwendungsmöglichkeiten für Objekte unter PHP ergeben sich also da, wo Funktionalitäten umfangreicher sind und möglichst wenig von der Umgebung beinflusst/beeinträchtigt werden sollen. Vorwiegend trifft das für die Teile zu, die im Hintergrund die Arbeit erledigen. Datenbankzugriff dürfte das prominenteste Beispiel sein. Weitere Anwendungsmöglichkeiten kann man in PEAR finden (siehe PEAR-Manual-Kapitel Packages). PEAR ist ein komplett objektorientiertes Framework für PHP und enthält schon jede Menge Lösungen für alle möglichen und unmöglichen Probleme. Und damit sich diese Lösungen nicht gegenseitig in Quere kommen sind sie zum einen in jeweils eine oder mehrere Klassen aufgeteilt, und zum anderen wird durch ein Verzeichnis- und Benennungsschema für eindeutige Klassennamen gesorgt.

    echo "$verabschiedung $name";

    1. Hi,

      Ich probier auch mal eine Antwort :-)

      *lol*

      Aber ja, da fällt mir im Zuge von größere Projekte noch was ein:

      1. Plugin-basierte Software ist meiner Meinung nach prozedural sehr viel schwerer zu realisieren. Ein einheitliches Interface gibt mir auch hier die Möglichkeit die unbekannte Komponente anzusteuern. Und um den Bogen zu PHP zurück zu bekommen, der in meinen anderen Ausführungen schrittweise den Bach runter ging, wenn man an phpBB oder ähnliche Software denkt, dann sind solche erweiterbaren Systeme ja durchaus vorhanden. Je mehr man da funktional arbeitet, um so mehr Zeilen muss man u.U. an der Basisinstallation verändern (Funktionsnamen hinterlegen etc.) bevor alles läuft.
      2. Die Sache mit der Übersichtlichkeit ist nicht zu vernachlässigen. Man möchte ja eigentlich versuchen sinnvolle Namen für Funktionen zu vergeben. Wenn man sich aber Projekte mit 1000en von Funktionen vorstellt, dann wird es irgendwann schwierig noch freie Namen zu finden (was schlussendlich wohl entweder in sehr komplexen Namen Modelname_Funktionsname o.ä., oder in Namespaces resultiert). Um auch hier wieder den Bogen zu (1) zu schlagen: Wie kann ein Modulprogrammierer sicherstellen, dass er eindeutige Namen verwendet?!

      MfG
      Rouven

      --
      -------------------
      ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
      1. Hallo,

        Aber ja, da fällt mir im Zuge von größere Projekte noch was ein:

        1. Plugin-basierte Software ist meiner Meinung nach prozedural sehr viel schwerer zu realisieren. Ein einheitliches Interface gibt mir auch hier die Möglichkeit die unbekannte Komponente anzusteuern. Und um den Bogen zu PHP zurück zu bekommen, der in meinen anderen Ausführungen schrittweise den Bach runter ging, wenn man an phpBB oder ähnliche Software denkt, dann sind solche erweiterbaren Systeme ja durchaus vorhanden. Je mehr man da funktional arbeitet, um so mehr Zeilen muss man u.U. an der Basisinstallation verändern (Funktionsnamen hinterlegen etc.) bevor alles läuft.
        2. Die Sache mit der Übersichtlichkeit ist nicht zu vernachlässigen. Man möchte ja eigentlich versuchen sinnvolle Namen für Funktionen zu vergeben. Wenn man sich aber Projekte mit 1000en von Funktionen vorstellt, dann wird es irgendwann schwierig noch freie Namen zu finden (was schlussendlich wohl entweder in sehr komplexen Namen Modelname_Funktionsname o.ä., oder in Namespaces resultiert). Um auch hier wieder den Bogen zu (1) zu schlagen: Wie kann ein Modulprogrammierer sicherstellen, dass er eindeutige Namen verwendet?!

        Rouven, unter Zweitens führst Du es selbst an (Die Sache mit der Übersichtlichkeit). Ich bitte Dich Deine Post durch zwei Zeilenumbrüche zu strukturieren. Ich bin Legastheniker und sehe beim betrachten eines Textes als allererste nur ein Zeichengewirr aus dem ich mich um so leichter befreien kann, desto strukurierter dieses Gewirr ist. Danke!

        Gruß aus Berlin!
        eddi