erläuterungen zu oop mit php5

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

  • erläuterungen zu oop mit php5

    wie ich auf unserem ersten treffen der php-sektion köln erwähnt habe, sitze ich gerade an einen anfängertutorial für oop mit php5. da ich mir zugegebenermaßen über ein paar dinge selber noch nicht hundertprozentig im klaren bin, benötige ich ein paar gute erläuterungen zu den folgenden themen:
    - exeptions
    - iteration

    zur überprüfung wären ggf. noch hinweise auf folgendes hilfreich
    - überladung
    - abstrakte methoden (slava hat es zwar erklärt aber wegen des folgenden bierkonsums ist nicht alles hängen geblieben, ging um zigarettenschachteln und aufmachen)
    - type hinting

    bitte keine hinweise auf sebastian bergmann oder das das handbuch. die habe ich schon durch. leider sind die erläuterungen ziemlich bescheiden.

    ach ja. und wenn möglich etwas, dass auch nicht studierte informatiker verstehen.

    gruß
    peter
    Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
    Meine Seite

  • #2
    Lern Java, dann wirst du das alles verstehen.

    Exceptions:
    Die kommen aus Sprachen, wo man nicht einfach z.B. String oder bei einem Fehler false zurückgeben kann, wie das in PHP der Fall ist. Außerdem kann man damit auch z.B. in einem Konstruktor Fehler zurückgeben, was sonst ja nicht möglich wäre.Im Fehlerfall wird die Methode beendet und es wird an den aufrufenden Code übergeben, um was für einen Fehler es sich handelt. Dafür werden normalerweise Unterklassen von Exception gebildet. Der aufrufende Code muss diese Exceptions dann abfangen, wobei er nur auf bestimmte Exceptions reagieren kann indem er den entsprechenden Klassennamen angibt, oder einfach alle von Exception abgeleiteten abfängt, indem er einfach Exception als Klassennamen angibt (man kann auch tiefere Vererbungshierarchien bauen und dann auch nur Exceptions einer Elternklasse abfangen, aber sowas wäre in PHP imho Overkill). Wenn eine Exception nicht abgefangen wird, wird sie einfach an die nächstaufrufende Methode weitergegeben (sieht man sehr schön, wenn man sich mal den Call-Stack ausgeben lässt mit Hilfe von XDebug oder debug_print_backtrace). Außerdem wird bei Exceptions in Java noch zwischen 2 Typen unterschieden, nämlich (1) wenn ein Programmierfehler aufgetreten ist und das Programm besser beendet werden sollte oder (2) wenn ein Fehler in der Umgebung aufgetreten ist (Datenbankverbindung fehlgeschlagen, irgendeine Datei nicht lesbar, etc.), das Programm aber sonst eigentlich weiterlaufen kann. z.B.:
    PHP-Code:
    class InvalidArgument************ception extends Exception {}
    class 
    DatabaseConnectionFailedException extends Exception {}
    class 
    foo {
        public function 
    doSomething($array) {
            if (!
    is_array($array)) {
                throw new 
    InvalidArgument************ception('Diese Methode braucht ein Array');
            }
            if (!
    mysql_connect(...)) {
                throw new 
    DatabaseConnectionFailedException('....');
            }
        }
        public function 
    doSomethingElse() {
            try {
                
    $this->doSomething(array());
            } catch (
    DatabaseConnectionFailedException $e) {
                
    // Diese Exception wird bereits hier behandelt
                
    echo 'Datenbankverbindung fehlgeschlagen';
            }
        }

    PHP-Code:
    $obj = new foo();
    try {
        
    $obj->doSomethingElse();
    } catch (
    InvalidArgument************ception $e) {
        
    // Diese Exception wurde eine Ebene höher durchgereicht
        
    die('Der Programmierer hat etwas falsch gemacht');
    } catch (
    Exception $e) {
        
    // hier landen alle anderen Exceptions, allerdings ist es schlechter Stil sowas zu machen

    Iteration:
    Man kann mit Hilfe von foreach nicht nur über Arrays iterieren, sondern auch über Objekte. Dazu muss man einfach das entsprechende Interface implementieren. Ein vereinfachtes Beispiel aus dem Code von meiner Homepage:
    PHP-Code:
    class Blog_EntryList implements Iterator {
        public function 
    current() { ... }
        public function 
    key() { ... }
        public function 
    rewind() { ... }
        public function 
    valid() { ... }
        public function 
    next() { ... }

    PHP-Code:
    $BlogEntries = new Blog_EntryList();
    $BlogEntries->sortBy 'created';
    $BlogEntries->limit 5;
    foreach (
    $BlogEntries as $entry) {
        echo 
    'Titel: ' $entry['title'] . '<br />';

    Überladung:
    Dabei geht es im Sinn von PHP5 OOP eigentlich nur um __get, __set, __call und __unset. Man kann das z.B. benutzen, um eine Datenbankklasse erst dann zu laden, wenn sie wirklich gebraucht wird (dadurch spart man ein paar Ressourcen):
    PHP-Code:
    class Core {
        public function 
    __get($name) {
            if (
    $name == 'DB') {
                include 
    'classes/DB.php';
                
    $this->DB = new DB();    // sobald $this->DB gesetzt wurde,
                                                       // wird nicht mehr die überladene 
                                                       // __get Methode aufgerufen
                
    return $this->DB;
        }

    PHP-Code:
    $core = new Core();
    $core->DB->query('....'); 
    Abstrakte Methoden:
    Du definierst eine Klasse, von der selbst keine Objekte erzeugt werden, sondern von der nur andere Klassen abgeleitet werden sollen. Dazu definierst du die Methoden als abstrakt, die von den abgeleiteten Klassen überschrieben werden müssen. Das ist vergleichbar mit einem Interface, nur dass ein Interface ausschließlich abstrakte Methoden beinhaltet (vereinfacht gesprochen) wobei eine Klasse, die abstrakte Methoden enthält (und damit automatisch zu einer abstrakten Klasse wird) noch bereits implementierte Methoden bereitstellen kann.
    Das Beispiel ist an den Haaren herbeigezogen:
    PHP-Code:
    class DirectoryScanner {
        abstract protected function 
    addFile($filename);
        public function 
    scanDir($directory) {
            
    $d dir($directory);
            while (
    $f $d->read()) {
                
    $this->addFile($f);
            }
        }
    }
    class 
    ImageScanner extends DirectoryScanner {
        protected function 
    addFile($filename) {
            if (
    substr($filename, -3) == 'jpg') {
                echo 
    'Image: ' $filename '<br />';
            }
        }

    Type Hinting
    Man kann angeben, was für Parameter eine Methode erwartet:
    PHP-Code:
    public function __construct(DB $Database) { ... } 
    Ich glaub das war jetzt so ziemlich der längste Beitrag, den ich je geschrieben hab
    hopka.net!

    Kommentar


    • #3
      kurz und verständlich.
      jetzt brauche ich nichts mehr dem Kropff zu erklären.
      Slava
      bituniverse.com

      Kommentar


      • #4
        @hopka

        dein beispiel für überladung ist IMHO kein beispiel dafür sondern
        für lazy instantiation.

        Überladung gibt es in php in dem sinne nicht. Man kann es simulieren
        was aber alles andere als schön ist.
        Dabei handelt es sich um verschiedene ausprägungen einer bestimmten
        methode. Der methodenname bleibt dabei erhalten, nur die signatur
        ändert sich. Die entscheidung welche methode aufgerufen wird trifft
        der compiler/interpreter in den gängigen sprachen anhand der
        typeconstraints. Einfaches beispiel in c++
        Code:
        #include <iostream>
        #include <string>
        
        class foo{
             public:
                 int bar(const std::string &){ return 1;}
                 int bar(const float &){ return 2;}
        };
        
        int main(int argc,char **argv){
        foo f;
        
        std::cout << f.bar("hallo") << std::endl;
        std::cout << f.bar(1) << std::endl;
        }
        Ausgabe:
        1
        2

        Allerdings wird das heute zunehmend über templatemethoden
        gelöst.

        greets

        [Nachtrag]
        Kurze anmerkung noch zum thema exceptions.
        Exceptions und exceptionshandling ist überall dort sinnvoll
        wo das program in einen unerwarteten zustand übergeht.
        Es handelt sich wortlich übersetzt um ausnahmen und
        ausnahmebehandlung. Das heisst auch dass man
        nicht hingehen soll und jede fehlerbehandlung auf
        exceptions umstellen soll. Das ist nicht sinnvoll.
        Im bezug auf exceptions wäre auch noch ein
        ausflug in den bereich exceptionsafety angebracht.
        Darüber gibt es genug literatur.
        Zuletzt geändert von closure; 07.02.2007, 09:46.
        (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

        Kommentar


        • #5
          Lern Java, dann wirst du das alles verstehen
          da habe ich mich mal vor jahren mit beschäftigt, aber das scheint eher ein hindernis zu sein, wenn man das auf php5 überträgt.

          trotzdem besonderen dank an hopka, werde mir das heute abend mal zu gemüte führen.
          jetzt brauche ich nichts mehr dem Kropff zu erklären
          hast du doch schon ist halt nur nicht mehr alles hängen geblieben

          gruß
          peter
          Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
          Meine Seite

          Kommentar


          • #6
            Original geschrieben von closure
            dein beispiel für überladung ist IMHO kein beispiel dafür sondern
            für lazy instantiation.
            Naja, es ist ein Beispiel für eine mögliche Verwendung von __get. Und bei PHP5 werden, wie ich geschrieben habe, __get, __set, __unset, __call und sogar noch __isset als Overloading bezeichnet:
            http://www.php.net/manual/en/languag...verloading.php
            Das man in anderen Sprachen etwas Anderes darunter versteht fand ich jetzt hier nicht so relevant.
            hopka.net!

            Kommentar


            • #7
              Irre ich mich, oder ist Überladen, einfach Überschreibung von methoden oder variablen von parent klasse?
              In jedem fall habe ich es so bei Java ,c++ und c# gelernt.

              PHP-Code:
              class Mitarbeiter{
               private 
              $name;
               public function 
              __construct($name){$this->name=$name;}
               public function 
              say($str){return $this->name." sagt: ".$str;}
              }


              class 
              Chef extends Mitarbeiter{
              //das ist Überladen von methoden
              function say($str){ return "(; ".strtoupper(parent::say($str))."...!";}
              }

              //test
              $Jungs=array(new Mitarbeiter("Müller"),
                                     new 
              Chef("Krause") ,
                                    new 
              Mitarbeiter("Kenntkeiner"));

              foreach(
              $Jungs as $geldverdiener){
                echo 
              $geldverdiener->say("Hi! wir wollen auch überleben")."<br />";

              Zuletzt geändert von Slava; 07.02.2007, 18:45.
              Slava
              bituniverse.com

              Kommentar


              • #8
                Eigentlich ja
                Für alle die Fehler suchen, gibts gratis tolle Debuggingmöglichkeiten:
                var_dump(), print_r(), debug_backtrace und echo.
                Außerdem gibt es für unsere Neueinsteiger ein hervorragendes PHP Tutorial zu PHP 4 und PHP 5 (OOP)
                Es heißt $array['index'] und nicht $array[index]! Und nein, das ist nicht egal!
                Dieses Thema lesen, um Ärger im Forum und verzögerte Hilfen zu vermeiden.

                Kommentar


                • #9
                  Also in den meisten Sprachen ist Überladen das, was closure oben erklärt hat. Bei PHP ist es das, was ich erklärt habe, bzw. das was im PHP Handbuch unter Overloading steht.
                  Mit Vererbung hat das allerdings beides erstmal nix zu tun.
                  hopka.net!

                  Kommentar


                  • #10
                    @hopka,

                    ein verweis auf die php-referenz und die benutzen termini ist
                    wie ein wikipediaeintrag als quelle. Aber ich verstehe jetzt warum
                    du das so beschrieben hast. So bekommen die armen user
                    keinen schreck wenn sie das auf kropffss seite gelernte mit dem
                    im php-manual vergleichen. Macht also durchaus sinn.
                    Vll. wäre dann eine anmerkung im tutorial gut, das besagt dass
                    die php-definition von overloading und die allgemeine oop-definition
                    divergieren.

                    @slava und shurakai
                    Was ihr meint ist etwas ähnliches aber nicht das selbe.
                    Die redefinition einer elternmethode in der kindklasse ist im prinzip
                    das hinzufügen einer bindung zum methodennamen. Es gibt dann
                    also nicht nur einen verweis von "methodennamen" auf die methode
                    sonder zwei oder mehr wobei die ziele dieser zeiger disjunkt sind.
                    Das wird in der literatur als overriding(warum wird das eigentlich nie
                    overwriting genannt?) bezeichnet. In diesem zusammenhang zu sind
                    dann noch zwei schlagworte zu nenne, nämlich lazy binding (späte bindung) und polymorphy. Das system entscheidet zur laufzeit welche
                    implementation einer bestimmten methode aufgerufen wird.
                    Während beim überladen bereits zur compile-/intepretierzeit genau
                    bekannt ist welche methode aufgerufen werden muss.

                    greets
                    (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

                    Kommentar


                    • #11
                      erst mal danke an alle.

                      ich bin schon fast soweit, dass mein tutorial fertig ist. ein paar fragen beschäftigen mich aber noch. erstmal nur eine:

                      welchen sinn haben statische methoden, wenn man sie als private oder protected deklariert. ich habe zwar das prinzip verstanden, aber mir fällt nicht ein verdammtes beispiel dazu ein.

                      gruß
                      peter
                      Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
                      Meine Seite

                      Kommentar


                      • #12
                        Naja, du kannst sie ja immer noch aus ner anderen statischen Methode heraus aufrufen.

                        Für simple String-Funktionen z.B. könnte das sinnvoll sein.

                        Kommentar


                        • #13
                          Original geschrieben von TobiaZ
                          Naja, du kannst sie ja immer noch aus ner anderen statischen Methode heraus aufrufen.
                          Für simple String-Funktionen z.B. könnte das sinnvoll sein.
                          klingt so, als ob du selber nicht überzeugt bist

                          peter
                          Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
                          Meine Seite

                          Kommentar


                          • #14
                            mir fällt nichts besonders praxis nahes ein.

                            Kommentar


                            • #15
                              Original geschrieben von TobiaZ
                              mir fällt nichts besonders praxis nahes ein.
                              also wenn keiner einen besseren einfall hat, dann buche ich das unter sinnlos ab

                              danke
                              peter
                              Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
                              Meine Seite

                              Kommentar

                              Lädt...
                              X