Interzeptor- und magische Methoden

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

  • Interzeptor- und magische Methoden

    Hallo zusammen

    ich überarbeite gerade mein OOP-Tutorial und muss mir jetzt ein paar Fragen stellen, mit denen ich bisher noch nicht konfrontiert wurde. Es geht also um Interzeptor- und magische Methoden. Ich dazu mal etliche Seiten durchforstet und bin auf viele widersprüchliche Angaben gestoßen

    1. Sind diese Begriffe identisch?
    Manche nutzen sie im selben Zusammenhang, andere dagegen unterscheiden zwischen ihnen.

    2. Gehören alle __-Methoden zu den magischen?
    Auch da habe ich sehr widersprüchliche Angaben gefunden. Einige zum Beispiel zählen __construct und __destruct dazu, andere nicht.

    3. Was zählt zu den Interzeptormethoden?
    In dem Fall sind die Aufzählungen extrem unterschiedlich. Manche zählen zum Beispiel __isset und __unset dazu, andere nicht.

    Die Wirkungsweise aller dieser Methoden ist mir vertraut. Ich habe nur fürchterliche Bauchschmerzen, wenn es um die Bezeichnung derselben geht. Ich hoffe, ich bekomme hier endlich mal eine klare Antwort. Das Internet ist da nicht so hilfreich.

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

  • #2
    Hallo Peter,

    was wer sagt ist erstmal total egal, denn stimmen tut es sowieso nur, wenn es mit der Doku übereinstimmt. Und die sagt:

    The function names __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state and __clone are magical in PHP classes.
    Interzeptormethoden sind generell nicht mit magischen Methoden gleichzusetzen, denn es können auch eigene Klassen irgendwelche Interzeptormethoden bereitstellen, die nicht magisch sind. Die oben genannten - außer den ersten beiden - sind alle Interzeptormethoden, wobei man sich selbst bei __construct und __destruct noch streiten könnte, ob sie nicht im weiteren Sinne auch als Interzeptor fungieren.

    Wenn es dir lediglich um eine zweifelsresistente Bezeichnung geht, würde ich bei "magische Methoden" bleiben und wenn die PHP-Doku Konstruktoren und Destruktoren dazuzählt, dann sind sie es auch.

    LG,

    Amica
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Danke für die Antwort. Dann habe ich ja alles richtig gemacht . Und korrekt verstanden. Wenn selbst ein Sebastian Bergmann da keine präzise Angaben macht, ist das schon ein wenig traurig.

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

      Kommentar


      • #4
        Alles was mit __ beginnnt ist magisch, denn es wird nicht explizit aufgerufen. In bestimmten Situationen ruft PHP diese Methoden eben einfach auf. That's magic!
        So sagts auch das Manual, siehe Amicas Beitrag.

        Interzeptoren sind die Teilmenge der magischen Methoden, die den Zugriff auf nicht existierende oder nicht zugreifbare Properties und Methoden abfangen und so vor Exceptions/Laufzeitfehlern schützen.
        __get, __set, __isset, __unset sind Interzeptoren für Properties.
        __call, __callStatic sind Interzeptoren für Methoden.

        __construct und __destruct sind keine Interzeptoren sondern einfach nur magisch. Denn sie fangen nichts ab. Wenn sie nicht existieren, passiert eben einfach nichts; insbesondere nichts schlimmes wie ein Laufzeitfehler.
        Magisch sind sie, weil man sie nicht explizit ruft. Das macht PHP ganz allein. Muss es auch, denn es gäbe gar keine Möglichkeit den Aufruf eines Konstruktors zu notieren. "new foo->foo()" ginge ebenso wenig wie "foo::foo()". Ersteres setzt ein existierendes Foo-Objekt voraus, letzteres würde verlangen, dass jeder Ctor eine Instanz der eigenen Klasse zurückgibt, was der Compiler wiederum nicht forcieren kann. Lange Rede ... Konstruktor und Destruktor müssen einfach magisch sein.
        Früher wurde die Magie des Kontruktors auf die Methode angewendet, die wie die Klasse hieß. Das gab Schwierigkeiten bei der Vererbung. Deswegen heißen jetzt alle Konstruktoren construct mit den __ vorweg, weil das eben alle Methoden bekommen, die irgendwie magisch sind (auch um Namenskonflikte zu vermeiden).
        Das selbe gilt für die anderen magischen Methoden, die keine Interzeptoren sind, wie __toString uws.

        Im PHP-Umfeld werden die Begriffe Interceptor und Overloading ganz anders verwendet als in der restlichen Softwarewelt. Das ist ziemlich bescheuert, denn Anfängern sagen die Begriffe sowieso nichts und Profis verwirrt die falsche Verwendung. Deshalb vermeide ich diese Begriffe im Zusammenhang mit PHP.

        Kommentar


        • #5
          @onemorenerd: Ziemlich gute Erklärung, die auch für Einsteiger in die Thematik verständlich sein sollte.

          @Kropff: Das kannste fast so in dein Tutorial übernehmen. (Sofern onemorenerd seinen Beitrag unter entsprechende „Lizenz” stellen mag.)
          I don't believe in rebirth. Actually, I never did in my whole lives.

          Kommentar


          • #6
            Zitat von wahsaga Beitrag anzeigen
            @onemorenerd: Ziemlich gute Erklärung, die auch für Einsteiger in die Thematik verständlich sein sollte.
            Da habe ich noch gewisse Zweifel . Das sagt der Anfängerversteher .
            Zitat von wahsaga Beitrag anzeigen
            @Kropff: Das kannste fast so in dein Tutorial übernehmen. (Sofern onemorenerd seinen Beitrag unter entsprechende „Lizenz” stellen mag.)
            Wenn ich das "übersetzt" habe, werde ich ihn natürlich lobend erwähnen. Und sagen, dass das auf seinem Mist gewachsen ist . In dem Zusammenhang würde mich noch interessieren, welche magischen Methoden außer __construct, __destruct und __toString nicht zu den Interzeptormethoden gehören. Was ist mit __sleep und __wakeup? Sind imho keine Interzeptormethoden. Oder? Habe allerdings noch nie mit denen zu tun gehabt.

            Und wo wir gerade beim Thema sind. Wie soll ich die denn nennen? Für den Konstruktor/Destruktor habe ich schon eine eigene Seite, Wie nenne ich den Rest? "Weitere magische Methoden" klingt nicht so toll.

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

            Kommentar


            • #7
              Zitat von Kropff Beitrag anzeigen
              Da habe ich noch gewisse Zweifel . Das sagt der Anfängerversteher .
              Kommt auf die Definition von „Anfänger” an.
              Wenn sich jemand mit OOP beschäftigen will, dann setze ich eigentlich voraus, dass er die Erstellung seines ersten “Hello World”-Progrämmchens schon hinter sich hat.

              Und wo wir gerade beim Thema sind. Wie soll ich die denn nennen? Für den Konstruktor/Destruktor habe ich schon eine eigene Seite, Wie nenne ich den Rest? "Weitere magische Methoden" klingt nicht so toll.
              Sind aber wohl „sonstige”, wenn du Kon- und Destruktor als die zunächst „wichtigsten” gesondert abhandeln willst.

              Ob du das strukturell als
              • Konstruktor/Destruktor
              • Weitere magische Methoden

              oder als
              • magische Methoden
                • Konstruktor/Destruktor
                • Weitere

              anbietest, kannst du dir ja noch überlegen …
              I don't believe in rebirth. Actually, I never did in my whole lives.

              Kommentar


              • #8
                Was ist mit __sleep und __wakeup? Sind imho keine Interzeptormethoden.
                Och, wohl doch....

                Und wenn man den Begriff "Interzeptormethoden" nicht ganz so eng sieht, dann gehören z.B. die Methoden des ArrayAccess Interface auch dazu.
                Evtl gar das count() des Countable Interface

                Am Rande:
                http://de.wikipedia.org/wiki/Interce...Entwurfsmuster)
                Wir werden alle sterben

                Kommentar


                • #9
                  Zitat von wahsaga Beitrag anzeigen
                  Kommt auf die Definition von „Anfänger” an.
                  Wenn sich jemand mit OOP beschäftigen will, dann setze ich eigentlich voraus, dass er die Erstellung seines ersten “Hello World”-Progrämmchens schon hinter sich hat.
                  Sehe ich genau so. Nur haben die "fortgeschrittenen" Anfänger immer Probleme mit der Terminologie.
                  Zitat von wahsaga Beitrag anzeigen
                  Sind aber wohl „sonstige”, wenn du Kon- und Destruktor als die zunächst „wichtigsten” gesondert abhandeln willst.

                  Ob du das strukturell als
                  • Konstruktor/Destruktor
                  • Weitere magische Methoden

                  oder als
                  • magische Methoden
                    • Konstruktor/Destruktor
                    • Weitere

                  anbietest, kannst du dir ja noch überlegen …
                  Werde ich wohl so machen. Auch wenn es blöde klingt.
                  Zitat von combie Beitrag anzeigen
                  Och, wohl doch....
                  Ach was . Mal abwarten, was die anderen sagen. ONEMOORENERD! HILFE!!!

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

                  Kommentar


                  • #10
                    Mein Senf ist public domain.

                    @combie: Du verwechselst den Begriff Interzeptor anscheinend auch mit dem, den man eben so aus der OO-Welt kennt. Vorsicht, das PHP-Manual verwendet diesen Begriff für etwas ganz anderes!

                    Die Allerweltsbedeutung, die man leider nicht in der Wikipedia findet (auch nicht in en) kann man hier mal nachlesen. In einem Satz kann man die wahre Bedeutung vielleicht so erklären: Interzeptoren sind Funktionen, die beim Ablauf eines Programms an einem bestimmten Punkt automatisch, also ohne expliziten Aufruf ausgeführt werden, weil sie durch einen wie auch immer gearteten Mechanismus für genau diesen Punkt registriert wurden.
                    PHP fehlt ein solcher Mechanismus. Gerade heute wurde in einem anderen Thread auch diese Seite verlinkt - da wird ein Mechanismus eingeführt, der über Annotations funktioniert. Im Prinzip steckt in Drupal etwas ähnliches, dort nennt man es Hooks ... wer es nicht kann es ja mal googeln. Wie gesagt ist es nur ähnlich, eigentlich nicht vergleichbar, aber es hilft vielleicht, das Konzept zu verstehen.

                    In der PHP-Welt wird der Begriff Interzeptor eigentlich nur für die paar Funktionen benutzt, die auf PHP: Overloading - Manual erklärt werden. Oder hat jemand weitere Vorkommen dieses Begriffs im Manual gefunden?
                    Das heißt, das PHP-Manual sagt Interzeptor, meint aber eine feststehende Tabelle von Punkten und Funktionen. So ein Punkt ist zum Beispiel das Erzeugen eines Objekts, die Funktion dazu __construct. Ein weiterer Punkt ist das Type Juggling eines Objekts zum String, die Funktion dazu __toString.
                    Normalerweise würde gar nichts passieren, aber dank der Tabelle passiert eben doch was (sofern die Funktionen implementiert wurde). Wahre Interzeption sieht aber anders aus. Da passiert sowieso was und man kann dafür sorgen, dass beim Eintreten bestimmter Bedingungen zusätzlich eine Interzeptormethode gerufen wird.

                    Egal wie weit man den Begriff Interzeptormethode dehnt, die Methoden aus irgendwelchen Interfaces gehören auf keinen Fall dazu! Man deklariert per class MyClass implements Countable, dass die eigene Klasse bestimmte Methoden, in diesem Fall count implementiert. Wenn die Methode aufgerufen wird, findet keine "Interzeption" (?) statt. Die wird einfach aufgerufen.
                    Die Tatsache, dass das Interface Bestandteil der Sprache ist, macht die Methoden nicht zu Interzeptoren.
                    Zuletzt geändert von onemorenerd; 08.11.2009, 18:27.

                    Kommentar


                    • #11
                      Zitat von onemorenerd Beitrag anzeigen
                      Mein Senf ist public domain.
                      Danke
                      Zitat von onemorenerd Beitrag anzeigen
                      In der PHP-Welt wird der Begriff Interzeptor eigentlich nur für die paar Funktionen benutzt, die auf PHP: Overloading - Manual erklärt werden. Oder hat jemand weitere Vorkommen dieses Begriffs im Manual gefunden?
                      Nicht im Manual, aber auf zig Seiten. Da haben sich wohl ein paar Leute ziemlich geirrt. Und das ist ja leider das Problem bei PHP. Man macht hier eine Ausnahme und da eine. Und zum Schluss reden alle aneinander vorbei. Ich persönlich mache Schluss für heute und werde mich sicher morgen wieder melden.

                      Danke an alle, die mir geholfen haben.
                      Peter
                      Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
                      Meine Seite

                      Kommentar


                      • #12
                        Ich würde das so strukturieren:
                        • magische Methoden
                          • Einleitung (Erklärung, Aufzählung, Gemeinsamkeiten, Kategorisierung)
                          • Konstruktor/Destruktor und __clone()
                          • Interzeptormethoden/Overloading
                            • Erklärung der Konzepte, Hinweis auf abweichende Bedeutung im PHP-Umfeld
                            • für Properties
                            • für Methoden

                          • Weitere mag. Methoden (für Serialisierung, var_export etc.)

                        Kommentar


                        • #13
                          Ich denke combie meint bei dem ArrayAccess-Interface, dass die Aufrufe über den eckige Klammern Operator auf die Methoden des Interfaces abgebildet werden, genauso wie die Funktion count auf eine Instanz des Countable-Interfaces angewendet die count-Methode aufruft.

                          Kommentar


                          • #14
                            Zitat von PHP-Desaster Beitrag anzeigen
                            Ich denke combie meint bei dem ArrayAccess-Interface, dass die Aufrufe über den eckige Klammern Operator auf die Methoden des Interfaces abgebildet werden ...
                            Aber genau diese "Abbildung" ist eine statische Tabelle mit zwei Spalten, links steht ein Sprachkonstrukt, rechts steht was gemacht wird.

                            Links steht
                            PHP-Code:
                            $a['foo'] = $bar
                            rechts steht
                            PHP-Code:
                            if (is_object($a) && $a instanceof ArrayAccess$a->offsetSet('foo'$bar); 
                            Das hat eben genau gar nichts mit Interception zu tun. Interception wäre, wenn der Interpreter vor jedem Aufruf einer Userland-Funktion nachschauen würde, ob sich für diesen Punkt ein Interzeptor registriert hat. Das könnte etwa so aussehen:
                            PHP-Code:
                            // Userland-Code:
                            function a() { echo 'foo'; }
                            function 
                            b() { echo 'bar'; }

                            // bevor der Interpreter a ausführt, soll er erst b ausführen
                            register_interceptor('a''b');

                            a(); // -> Ausgabe "barfoo" 
                            Man könnte auch mehrere Interzeptoren für a registrieren. Sie würden in der Reihenfolge ihrer Registrierung aufgerufen. Wie man es von register_shutdown_function() kennt.

                            Besonderer Clou bei echten Interzeptoren: Man kann einen Interzeptor für einen Interzeptor registrieren. Da dann aber auch sowas möglich ist
                            PHP-Code:
                            // bevor der Interpreter a ausführt, soll er erst b ausführen
                            register_interceptor('a''b');
                            // bevor der Interpreter b ausführt, soll er erst a ausführen
                            register_interceptor('b''a'); 
                            ist die Verwaltung der Registrierungen zur Laufzeit ziemlich kompliziert.
                            Ganz verzwickt wird es, wenn Interzeptoren den weiteren Programmverlauf steuern können, zum Beispiel indem sie die Ausführung weiterer Interzeptoren verhinden oder sogar den Aufruf der eigentlichen Funktion, für die der Interzeptor registriert wurde (bailOut). Naja und dann könnte man theoretisch nicht nur Funktionsaufrufe als Interception Points anbieten sondern beliebige Sprachkonstrukte wie den -> Operator. Ein Interzeptor für -> könnte dann erstmal prüfen, ob das Objekt links vom Operator überhaupt die Property oder Methode rechts vom Operator besitzt und der Zugriff erlaubt ist - wozu es natürlich das Links und Rechts auch kennen müsste.

                            Dieses Thema ist ein weites Feld, sprachentheoretisch extrem interessant, aber kaum umsetzbar.
                            Wer in OO-PHP Interception haben will, muss sich mit dem Chain of Responsibility Pattern behelfen. Für non-OO-PHP ist Drupals Idee von Hooks ganz brauchbar.


                            Disclaimer: In diesem Beitrag habe ich die Begriffe Interzeptor/Interception ausschließlich in ihrer normalen Bedeutung verwendet, nicht so wie PHP es versteht. Um zu beschreiben was PHP macht, braucht man die Begriffe eigentlich gar nicht. Die Umschreibung "magisch" genügt und verdeckt die im Interpreter fest implementierte Tabelle, die ich oben andeutete.
                            Zuletzt geändert von onemorenerd; 08.11.2009, 19:26.

                            Kommentar

                            Lädt...
                            X