Verständnigsfrage zu OOP in PHP

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • mermshaus
    antwortet
    Das ist alles nicht so leicht zu beantworten.

    „OOP“ und „prozedural“ umfasst mehr als Syntax und ist nicht immer so ganz trennscharf. Damit geht es schon los. Man kann zwar sagen, dass es OOP ist, sobald Funktionalität rein syntaktisch in Klassen und Methoden abgelegt ist. Das ist sicherlich nicht in dem Sinne falsch. Es lässt sich aber auch mit Objekten in einem Stil programmieren, der ziemlich dem entspricht, was gemeinhin mit „prozedural“ gemeint ist. (Der Code am Ende von deinem Beispiel 1 geht vielleicht ein wenig in die Richtung.) Auch umgekehrt ist es sicherlich möglich, auch ohne Klassen Code zu schreiben, der von der Denkweise Richtung OOP geht. (Ein Beispiel dafür sind die „prozeduralen“ mysqli-Funktionen, die als ersten Parameter immer die Instanz erwarten, mit der sie arbeiten. Das bietet sich in eigenem Code aber jetzt nicht unbedingt an, weil viele Hilfestellungen fehlen, die in Klassen enthalten sind. Zum Beispiel Sichtbarkeiten.)

    Es gibt keine Patentantwort, wie man das, was du beschreibst und nachfragst, „richtig“ macht. Dazu sind zum Beispiel die denkbaren Anforderungen zu vielfältig. Verdeutlichung dazu: Wie hebt man ein Loch aus? Wenn es darum geht, einen Busch zu pflanzen, ist ein Spaten das richtige Werkzeug. Wenn es um ein Fundament für ein Hochhaus geht, braucht es ungleich komplizierteres Gerät. Zudem gilt es viel mehr zu beachten, und es kommen wahrscheinlich etliche Anforderungen hinzu, die nur noch sehr begrenzt mit dem tatsächlichen Vorgang des Grabens zu tun haben.

    Ich habe im Laufe der Jahre so einige Versuche gelesen (und auch selbst zu verfassen versucht), den Aufbau eines einfachen OOP-basierten Systems zu erklären. Es ist sehr schwierig, irgendwo sinnvoll einen Cut zu machen, wo man mit der Abstraktion und Komplexität aufhört und was man noch mit reinnimmt und was nicht mehr. Man kommt zwangsläufig vom Hundertsten ins Tausendste. Mein Tipp ist deshalb bei so was immer, mal einen Blick in Demoprojekte oder Tutorials von bestehenden Frameworks und CMS und Template-Engines zu werfen, um ein Gefühl für die Sache zu bekommen. Die haben sich alle sehr intensiv mit genau den Fragen befasst, die du auch gerade hast, auch wenn man das auf den ersten Blick nicht gleich vermutet. Unvollständige Liste der üblichen Verdächtigen: Silex, Laravel, Symfony, Twig, WordPress, … Das ist ganz bestimmt gut investierte Zeit und wird eine Menge Dinge klären.

    Noch subjektiver zu einigen Abschnitten deiner Beiträge:

    Lagere ich wirklich alles in Funktionen/Methoden der Klasse aus und rufe dann lediglich die Methoden auf die mir dann HTML-Abschnitte generieren?
    Wirklich alles oder doch wieder eine Kombination aus konventioneller Programmierung in der index.php + Klassen?
    Ich habe darüber gerade noch mal einige Zeit nachgedacht, aber das ist letztlich einfach vom Projekt abhängig und von dir als Entwickler und deinen Erfahrungen und dem, was du machst oder machen willst.

    Zur Positionierung von HTML: Es wird in dem Bereich oft mit etwas gearbeitet, das sich so grob „View-Script“ nennt oder „Template“. Das sind Dateien mit HTML-Fragmenten (in der Regel keine kompletten Seiten), die PHP-Code enthalten, der nur Ausgabelogik durchführt (einfache Schleifen und Bedingungen), keine Geschäftslogik. Die werden oft mit der Endung *.phtml abgelegt, um sie von normalen PHP-Dateien mit (in der Regel) einer Klasse pro Datei zu unterscheiden. Bei Nutzung von einer Template Engine ersetzt deren Syntax den PHP-Code in diesen Dateien, aber mit PHP geht es auch. Diese Templates werden dann in einer PHP-Klasse eingebunden (heißen in der Regel was mit „View“), der auch die darzustellenden Daten gesetzt werden, auf die dann in der Template-Datei zugegriffen werden kann.

    Hier wird es etwas weiter erklärt:

    - https://www.smashingmagazine.com/201...hp-templating/

    Diese Templates sind untereinander oft über mehrere Ebenen geschachtelt. Es gibt in der Regel eines oder mehrere Rahmen-Templates (Layouts genannt), die den HTML-Körper (html, head, body, …) enthalten und Platzhalter für die Ausgabe anderer Templates, die dann Haupt-Content, Seitennavigation und dergleichen enthalten. Die können dann in sich auch wiederum noch mal weitere Templates einbinden usw. Dazu meist noch einige Hilfs-Templates (so eine Art „Helfer-Funktionen“), die Bausteine enthalten, die man an verschiedenen Stellen benötigt. Etwa den Rahmen für eine Box oder ein Template, das Eingabedaten in einer einfachen Tabelle darstellt. (Das sind oft Decorators.)

    Das war jetzt leider keine tolle Erklärung, weil sofort wieder das oben beschriebene Problem auftaucht, dass kaum ein Ende zu finden ist und dass es schwierig ist, Teilaspekte wie diese Variante des Templatings losgelöst zu betrachten.

    Das wird dir aber sicherlich alles schnell wieder begegnen, wenn du dich ein wenig in bestehende Frameworks oder dergleichen einarbeitest.

    Will ich z.B. im Body der HTML-Seite eine Navigationsleiste machen, rufe ich an entsprechender Stelle die Methode 'createNaviBar()' der Klasse 'Header' auf (Header wäre dann die Klasse die sich um den Kopfbereich der Seite widmet bzw. diese erstellt und die Methode 'CreateNaviBar' generiert mir dann die Navigationsleiste).
    Das kann man so in der Art machen, auch wenn das spontan eher kleinteilig wirkt. Spezialisierte View-Klassen ergeben Sinn, es tut aber oft auch eine Instanz einer generischen View-Klasse, der man als HTML-Template dann die „PHTML“-Datei setzt, die zum Beispiel die Navigationsleiste enthält. Die Instanz könnte man als Parameter der übergeordneten View zuweisen, die ihrerseits das HTML für das Rahmen-Layout enthält.

    Ganz grob:

    PHP-Code:
    $layout = new View('scripts/layout.phtml');
    $header = new View('scripts/header.phtml');

    $layout->set('headerContent'$header);
    echo 
    $layout->render(); 
    Und in layout.phtml könnte dann zum Beispiel stehen:

    Code:
    <!doctype html>
    <html>
    <head>
      ...
    </head>
    <body>
      <?=$this->get('headerContent')->render()?>
    
      ...
    </body>
    </html>
    Das jetzt aber wirklich nur ganz schematisch als Pseudocode.

    Wie unterteile ich die Klassen dann am besten? Habe ich eine 'gottgleiche' Klasse welche dann jeweils Methoden für die einzelnen Bereiche bereithält?
    Gott-Klassen sind nie gut. Mit einer zu feinen Verästelung und Unterteilung wird es aber auch mühselig. Hängt von den Anforderungen des Projekts ab. Ich mache es gern erst mal nicht zu komplex und warte erst mal ab, wo sich Redundanzen ergeben (weil ich an verschiedenen Stellen ähnliche Design-Elemente/Widgets haben will) oder wo ein Template zu komplex wird, und unterteile dann weiter.

    (Habe keine Zeit mehr. Vielleicht nachher noch mehr.)
    Zuletzt geändert von mermshaus; 28.03.2017, 18:33.

    Einen Kommentar schreiben:


  • Master0Blicker
    antwortet
    Niemand der mich etwas aufklären kann?
    Berichtet mir doch lediglich wie ihr das macht.
    Arbeitet ihr nur objektbasierend oder eine Kombination aus prozedualem Code + Klassen/Objekte (Prozedualer Code in PHP-Datei + Objekte für bestimmte Dinge wie Datenbanken, Mailversand, Bildbearbeitungen usw..)?

    Ich stelle mir das am saubersten als reine OOP vor wo jeder Bereich, jeder DIV-Container, jede Liste in Klassen ausgelagert wird wessen Methoden das an Ort und Stelle generieren.
    Und in dieser Vorgehensweise stellt sich die Frage wie die Objekte aufgeteilt werden. Eine Gott-Klasse die wiederum andere Klassen enthält die sich um die einzelnen Elemente kümmern, eine Gott-Klasse die sich selber um die einzelnen Elemente kümmert (-> jeder Bereich/Element als eigene Funktion/Methode, was ich mir schwer vorstellen kann) oder doch das Root-Dokument (PHP-Datei) als Basis und in dieser wimmelt es von den einzelnen Objekten die die einzelnen Bereiche/Elemente der HTML-Datei generiert?


    Beispiel 1, reine OOP:
    PHP-Code:
    <?php
        
    class LoginClass {
            public 
    $status 0;
            public 
    $lastLogin;
            private 
    $LoginVersuche 0;
            
            public function 
    Login($username$password)
            {
                
    mach_irgendwas();
                
    #usw.
            
    }
            
            public function 
    showLogin()
            {
                
    erstelle_Login_Formular();
                
    #usw.
            
    }
        }
        
        class 
    Title
        
    {
            private 
    $title;
            
            function 
    __construct($title) {
                   
    $this->title $title;
               }
            
            public function 
    createTitle()
            {
                echo 
    sprintf("<title>%s</title>"$this->title);
            }
        }
        
        class 
    HTML
        
    {
            
            private 
    $css_ref;
            private 
    $objTitle;
            private 
    $objLogin;
            
    #usw.
            
            
    function __construct($title) {
                 
    $this->objTitle= new Title($title);
            }
            
            public function 
    setCSSRef($path_css)
            {
                
    $this->$css_ref $path_css;
            }
            
            public function 
    createHead()
            {
                echo 
    "<head>\n";
                
    objTitle->createTitle();
                echo 
    sprintf("<link rel='stylesheet' href='%s'>\n"$this->css_ref);
                echo 
    "<head>\n";
            }
            
    #usw. viele weitere Funktionen die eben die ganze HTML letzendlich erstellen
            
            
        
    }
        
        
    $objHTML = new HTML("testprojekt");
        
    $objHTML->setCSSRef("stylesheet.css");
        
        
    $objHTML->openHTML();
        
    $objHTML->createHead();
        
    $objHTML->createBody();
        
    $objHTML->createLogin();
        
    #usw..
        
    $objHTML->closeHTML();
        
    ?>

    Beispiel 2, OOP 'light' (-> Alle o.g. Klassen werden nicht in eine Gott-Klasse verschoben sondern werden in der index.php instanziert und in einem Mix aus prozedualem Code und Objekten genutzt):
    PHP-Code:
    <?php
        $objHead 
    = new HeadClass():
        
    $objTitle = new TitleClass("testprojekt");
        
    $objDB = new PDO(".., .., ..");
    ?>
    <html>
    <!--diverse andere Dinge in HTML-->
    <?php
    $objHead
    ->create();
    #usw.
    ?>
    </html>



    Beispiel 3, OOP + prozedualer Code:
    (höchstwahrscheinlich entfällt diese Methode. Ich will es dennoch mal in das Rennen schicken)

    PHP-Code:
    <?php
        $debug_mode 
    1;
    ?>
    <html>
    </head>
    <?php
        
    if($debug_mode == 1)
        {
            
    ini_set('display_errors''On');
        }else{
            
    ini_set('display_errors''Off');
        }
    ?>
    <title>testprojekt</title>
    <link rel="stylesheet" href="stylesheet.css">
    </head>
    <?php
        
    #Mach irgendwas
        #Mach nochwas, aber die DB wird hierzu benötigt->erstelle ein PDO-Objekt
        
    $objDB = new PDO (".., .., ..");
        
    #usw.
        #prozedualer Code...
        #jetzt wird irgendwas per eMail verschickt:
        
    $objEmail = new Sendmail("server""port""usw");
        
    $objEmail->send();
        
    #usw.
        
    ?>

    Ich hoffe damit verständlich gemacht zu haben was ich wissen will.
    Wie macht ihr das? Reine OOP ohne Kompromisse wie in Beispiel 1?
    OOP zweckmäßig und sinnig verwenden wie in Beispiel 2?
    OOP verwenden punktuell und nur da wo es zweckmäßig erscheint wie in Beispiel 3? Beispiel 3 ist wahrscheinlich zu ignorieren, ich wollte es nur aufzeigen um beide extremen in den Topf hier geworfen zu haben).

    Einen Kommentar schreiben:


  • Master0Blicker
    hat ein Thema erstellt Verständnigsfrage zu OOP in PHP.

    Verständnigsfrage zu OOP in PHP

    Hallo Leute,

    ich hätte da mal eine, für mich wichtige, Verständnisfrage die ihr mir wahrscheinlich schnell beantworten könnt.

    Ich hatte vor einigen Jahren ein kleines PHP-Projekt für mich selber gemacht bei welchem ich ziemlich dilettantisch vorgegangen bin.
    Ich habe mein ganzes Script in die index.php gelegt und habe selten bis gar nicht Klassen/Objekte erstellt sondern PHP als Zeilenablaufprogramm erstellt ('konventionelle Programmierung'). War jedenfalls sehr wirr und unübersichtlich.

    PHP ist jedoch eine OOP-Sprache (also Klassen mit Methoden und Eigenschaften) und daher will ich es jetzt besser machen und 'richtig' OOP programmieren.

    Die Frage ist aber: wie weit soll es OOP sein und wie sieht das dann genauer aus?

    Lagere ich wirklich alles in Funktionen/Methoden der Klasse aus und rufe dann lediglich die Methoden auf die mir dann HTML-Abschnitte generieren?
    Wirklich alles oder doch wieder eine Kombination aus konventioneller Programmierung in der index.php + Klassen?

    Will ich z.B. im Body der HTML-Seite eine Navigationsleiste machen, rufe ich an entsprechender Stelle die Methode 'createNaviBar()' der Klasse 'Header' auf (Header wäre dann die Klasse die sich um den Kopfbereich der Seite widmet bzw. diese erstellt und die Methode 'CreateNaviBar' generiert mir dann die Navigationsleiste).

    Wie unterteile ich die Klassen dann am besten? Habe ich eine 'gottgleiche' Klasse welche dann jeweils Methoden für die einzelnen Bereiche bereithält?
    (objMyPage->createHeadNaviBar(), objMyPAge->createLoginBox(), usw..)

    Oder erstelle ich einzelne Klassen für einzelne Bereiche und rufe diese aus dem Root-Dokument (z.B. index.php) auf?
    (objHeadNavi->createNaviBar(), objLoginBox->createLoginBox(), usw..)

    Oder erstelle ich doch eine Master-Klasse welche dann weitere Objekte für die verschiedenen Bereiche enthält welche ich dann aus dem Root über die Masterklasse dann jeweils aufrufe?
    (objMyPage->objHeadNavi->createNavBar(), objMyPage->objLoginBox->createLoginBox(), usw.)


    Man könnte ja total übertreiben und in dem Root-Dokument gar keine HTML-Tags oder der Gleichen setzen (also nicht einmal <html></html>, <head></head>, <title></title und <body></body> sondern ALLES eine oder mehrere Klassen machen lassen.

    Entschuldigt meine plumpen Fragen, aber wenn man es richtig machen möchte, dann sollte man sich ja nicht bereits am Anfang in den falschen Zug setzen.. und das versuchei ch nun zu vermeiden bzw. es gleich im Kern richtig machen.


    Ich hoffe auf aufschlussreiche Antworten und bedanke mich schon einmal im Voraus dafür oder zumindest für das Lesen bis hierhin.
Lädt...
X