frankx: Zend Frameworks Request Objekt - wie wird es "rumgereicht"

Hellihello (vielleicht wieder dedlfix?),

im ZF gibt es ein Request-Objekt, dass zuerst vom Frontcontroller beim Dispatchen instanziiert wird, falls nicht vorhanden, und dann von den weiteren Controllern (Router, Action Controller) bearbeitet (?), verarbeitet (?).

Ein Response-Objekt wird ja auch erstellt, an dem fummelt aber scheints nur der ActionController (oder die, wenn mehrere in Reihe geschaltet sind) herum.

Ich finde irgendwie nicht wirklich heraus, wie die einzelnen Klassen/Instanzen wissen, wo sie das RequestObjekt abholen. Beim Front-Controller, holen sie es sich da, oder bekommen sie es übergeben? Im Grunde ja einfach mal im Code schauen, aber so versiert bin ich da (noch ?) nicht.

http://framework.zend.com/manual/en/zend.controller.basics.html

Dank und Gruß,

frankx

--
tryin to multitain  - Globus = Planet != Welt
  1. echo $begrüßung;

    Ich finde irgendwie nicht wirklich heraus, wie die einzelnen Klassen/Instanzen wissen, wo sie das RequestObjekt abholen. Beim Front-Controller, holen sie es sich da, oder bekommen sie es übergeben?

    Sie bekommen es immer durchgereicht. Die Haupt-Methode von Zend_Controller_Front ist dispatch(). Dort wird das Request-Objekt erzeugt, wenn keins übergeben wurde, was der Normalfall ist. Mittels setRequest() landet es in $this->_request. Analoges passiert mit dem Response-Objekt. (Plugin-Handling lass ich mal aus.) Der Router wird instantiiert, anschließend der Dispatcher, wobei ihm das Resp-O übergeben wird. Vom Router wird route() aufgerufen und das Req-O übergeben. Der ermittelt Modul, Controller und Action und hinterlegt diese Werte im Req-O. Vom Dispatcher wird nun dispatch() aufgerufen und dabei sowohl das Req-O als auch das Resp-O übergeben[1]. Dort wird der passende Action-Controller ermittelt und instantiiert, wobei wiederum Req-O und Resp-O übergeben werden. Vom AC wird dispatch() aufgerufen mit dem Action-Namen als Parameter. Die darin aufgerufene Action-Methode kann nun auf die beim Instantiieren des AC übergebenen Resp-O und Req-O zugreifen.

    Im Grunde ja einfach mal im Code schauen, aber so versiert bin ich da (noch ?) nicht.

    Genau das musste ich auch machen, da meine aktive Zeit mit dem ZF bereits vor dem Erscheinen der Version 1 endete.

    [1] Dieser Aufruf steckt genauer gesagt in der Dispatch-Schleife, die dafür sorgt, dass mehrere Actions aufgerufen werden können. Die Übergabe des Resp-O kurz nach der Instantiierung des Dispatchers mit setResponse() scheint mir ein Überbleibsel aus einer älteren Funktionalität zu sein. Da passiert nichts weiter außer dass der Dispatcher es in seinem $this->response ablegt. Mehr ist da augenscheinlich auch nicht geplant, denn es ist nur eine Accessor-Funktion. Nun passiert Plugin- und Route-Handling wobei der Dispatcher nicht involviert ist. Die Plugins können mit ihrer Referenz auf das Resp-O selbiges beeinflussen, was sich natürlich auch in $this->_response und $dispatcher->_response niederschlägt, da das auch nur Referenzen darauf sind. Nun erfolgt $dispatcher->dispatch() und da wird wieder die Referenz auf das Resp-O übergeben ...
    Da unter PHP5 ja Objekte generell als Referenz übergeben werden, reichte es, wenn sowohl Req-O als auch Resp-O einmalig beim Instantiieren der jeweiligen Beteiligten übergeben werden und nicht bei jedem Aufruf einer Methode eines Beteiligten neu vom FrontController übergeben wird. Mir will keine Begründung einfallen, warum das da doppelt gemoppelt ist, außer dass man es später wegoptimieren und für Release X eine Geschwindigkeitssteigerung proklamieren kann :-)

    echo "$verabschiedung $name";

    1. Hellihello dedlfix,

      Sie bekommen es immer durchgereicht. Die Haupt-Methode von Zend_Controller_Front ist dispatch(). Dort wird das Request-Objekt erzeugt, wenn keins übergeben wurde, was der Normalfall ist. Mittels setRequest() landet es in $this->_request. Analoges passiert mit dem Response-Objekt. (Plugin-Handling lass ich mal aus.) Der Router wird instantiiert, anschließend der Dispatcher, wobei ihm das Resp-O übergeben wird. Vom Router wird route() aufgerufen und das Req-O übergeben. Der ermittelt Modul, Controller und Action und hinterlegt diese Werte im Req-O. Vom Dispatcher wird nun dispatch() aufgerufen und dabei sowohl das Req-O als auch das Resp-O übergeben[1]. Dort wird der passende Action-Controller ermittelt und instantiiert, wobei wiederum Req-O und Resp-O übergeben werden. Vom AC wird dispatch() aufgerufen mit dem Action-Namen als Parameter. Die darin aufgerufene Action-Methode kann nun auf die beim Instantiieren des AC übergebenen Resp-O und Req-O zugreifen.

      Könnte man zusammenfassen mit folgendem Beispielcode?

        
        
      <?php  
      class MySomeContentClass  
      {  
       // to keep some test-values  
       protected $_myArray = array();  
        
       // set test values  
       public function addKeyValue($key,$value) {  
        $this->_myArray[$key]=$value;  
       }  
        
       // to get set testvalues  
       public function getMyArray() {  
        return $this->_myArray;  
       }  
      }  
        
      abstract class MyTestController  
      {  
       // will be instance of MySomeContentClass  
       protected $_mySomeContentObject = null;  
        
       // to be defined in extending class  
       public function __construct() {  
       }  
        
       // zugriff auf das ContentObjekt  
       protected function _getMySomeContentObject() {  
        return $this->_mySomeContentObject;  
       }  
      }  
        
      class MyTestController1 extends MyTestController  
      {  
       // weitere Instanz, eines zweiten Kontollers  
       protected $_myTestController2 = null;  
        
       public function __construct() {  
        // initiate ContentObjekt  
        $this->_mySomeContentObject = new MySomeContentClass();  
        // set test key-value-pair via own setter function  
        $this->_getMySomeContentObject()->addKeyValue("class1","value1");  
        // instanciate second controller - passing the ContentObjekt  
        $this->_myTestController2 = new MyTestController2($this->_getMySomeContentObject());  
       }  
        
       // get the ContentObjekt-contentArray  
       public function spitItOut() {  
        return $this->_getMySomeContentObject()->getMyArray();  
       }  
        
      }  
        
      class MyTestController2 extends MyTestController  
      {  
        
       // gets first parameter an instance of MySomeContentClass  
       public function __construct(MySomeContentClass $instance) {  
        //sets passed object to private var - setter function missing for this test  
        $this->_mySomeContentObject = $instance;  
        // set second test key-value-pair via own setter function  
        $this->_getMySomeContentObject()->addKeyValue("class2","value2");  
       }  
      }  
        
      // initiate first controller, who will automatically initiate the second one in constructor  
      $controll1 = new MyTestController1;  
      // test output  
      var_dump($controll1->spitItOut());  
      /*  
      array(2) {  
        ["class1"]=>  
        string(6) "value1"  
        ["class2"]=>  
        string(6) "value2"  
      }  
      */  
        
      
      

      Im Grunde ja einfach mal im Code schauen, aber so versiert bin ich da (noch ?) nicht.

      Genau das musste ich auch machen,

      Verdammt, ich verstrick mich da noch immer, obwohl ich es eigentlich lesen können müsste, da mir die einzelnen Bestandteile eigentlich langsam klar werden.

      da meine aktive Zeit mit dem ZF bereits vor dem Erscheinen der Version 1 endete.

      Warum denn das? Ich denke ja nach wie vor, wer was von PHP versteht, sollte die Grundzüge des ZF begreiffen. Aber das tust du ja, nur warum hast du aufgehört damit?

      Da unter PHP5 ja Objekte generell als Referenz übergeben werden

      s.o. code-beispiel, oder?

      außer dass man es später wegoptimieren und für Release X eine Geschwindigkeitssteigerung proklamieren kann :-)

      Denken die Damen und Herren bei Zend an sowas?
      Dank und Gruß,

      frankx

      --
      tryin to multitain  - Globus = Planet != Welt
      1. echo $begrüßung;

        Könnte man zusammenfassen mit folgendem Beispielcode?

        Ich sehe nicht, worauf du mit dem Beispiel hinauswillst.

        Im Grunde ja einfach mal im Code schauen, aber so versiert bin ich da (noch ?) nicht.
        Genau das musste ich auch machen,
        Verdammt, ich verstrick mich da noch immer, obwohl ich es eigentlich lesen können müsste, da mir die einzelnen Bestandteile eigentlich langsam klar werden.

        Übung macht den Meister. Weißt du doch.

        da meine aktive Zeit mit dem ZF bereits vor dem Erscheinen der Version 1 endete.
        Warum denn das? Ich denke ja nach wie vor, wer was von PHP versteht, sollte die Grundzüge des ZF begreiffen. Aber das tust du ja, nur warum hast du aufgehört damit?

        Python ist für mich interessanter geworden und Django war flexibler.

        Da unter PHP5 ja Objekte generell als Referenz übergeben werden
        s.o. code-beispiel, oder?

        Ja, da übergibst du Objekte und eine Änderung wird aufgrund der Referenz ja nur in dem einen Original vorgenommen, auf das alle anderen lokalen Referenzen zeigen.

        außer dass man es später wegoptimieren und für Release X eine Geschwindigkeitssteigerung proklamieren kann :-)
        Denken die Damen und Herren bei Zend an sowas?

        Ja, das las ich mal als Argument auf der Mailingliste und das ist auch sinnvoll so. Zuerst werden die Features geplant und implementiert, wobei sich natürlich herausstellt, dass manches anders benötigt wird oder erweitert werden muss. Beim Erweitern muss man vielleicht Kompromisse schließen oder hat grad keine Idee, wie man optimal alles unter einen Hut bringen kann oder will erstmal die Fatures implementiert haben ohne vielleicht die betroffene(n) Komponente(n) komplett und auf bessere Weise umzustricken. Das ist in praktisch jedem größeren Projekt so, besonders dann wenn viele Autoren und Anwenderwünsche daran beteiligt sind. Als zweiten Schritt kann man sich dann darauf konzentrieren, das vorhandene zu optimieren. Schau dich um, du wirst das Muster noch öfter entdecken: X.0 = jede Menge neue Features, X.1 = hauptsächlich Optimierung, X.folgende = weitere Optimierung und das eine oder andere neue Feature.

        echo "$verabschiedung $name";

        1. Hellihello dedlfix,

          Ich sehe nicht, worauf du mit dem Beispiel hinauswillst.

          Vermutlich eher eine Übung für mich. Nehm ich ein Objekt, in dem Content gespeichert wird. Übergibt ein Controller das Objekt an den nächsten. In erster Linie ein Versuch wohl, das passing by reference auszuprobieren, mit ein bisschen good-practice-Versuchen im Code.

          Python ist für mich interessanter geworden und Django war flexibler.

          Wie kommt sowas? Für Web Sachen? Im Zusammenhang mit einem größeren Projekt? Oder mit Pythons Server Zope? Und gibts dann nicht noch Plone als CMS?

          Dank und Gruß,

          frankx

          --
          tryin to multitain  - Globus = Planet != Welt
          1. echo $begrüßung;

            Python ist für mich interessanter geworden und Django war flexibler.
            Wie kommt sowas? Für Web Sachen? Im Zusammenhang mit einem größeren Projekt? Oder mit Pythons Server Zope? Und gibts dann nicht noch Plone als CMS?

            PHPs mangelnde Unicode-Unterstützung war wohl der Hauptgrund. Version 6 ließ damals schon eine Weile auf sich warten und macht das immer noch. Python ist nicht so stark auf das Web ausgelegt wie PHP, was aber auch als Vorteil gewertet werden kann. Besonders der interaktive Interpreter ist für ein schnelles Probieren wesentlich besser geeignet als der übliche PHP-Weg. Zope bekam nur einen kurzen Blick ab. Das ist älter als die Steinkohle und fühlte sich auch so an. Plone kenne ich nicht weiter. Derzeit nutze ich nur Einzelteile, einige vorgefertigte wie das Template-System Cheetah, weil es so flexibel ist, nicht nur hauptsächlich Web-Dokumente zu unterstützen. Das Webframework ist selbst entwickelt und enthält auch nur das was ich brauche. Die Ideen dazu sind zusammengetragen aus allem was mir so unter die Finger kam und ich für gut und brauchbar befunden habe.

            echo "$verabschiedung $name";