Lookupable

Lookupable

Objekte von Klassen, die du als "Lookupable" kennzeichnest, werden vom n2n an einem zentralen Ort verwaltet und können auch für Depency Injections verwendet werden.

  1. Lookupable
  2. Session Scoped
  3. Application Scoped

Lookupable

Nutze eines der folgenden Markierungs-Interfaces, um eine Klasse als "lookable" zu kennzeichnen. Objekte dieser Klassen werden vom n2n instanziert und zentral verwaltet. Du kannst sie über [Thomas, phpdoc]n2n\model\LookupableManager::lookup()[/Thomas, phpdoc] anfordern oder dir per Dependency Injections übergeben lassen.

Interface Verhalten
n2n\model\Lookupable Klasse wird jedesmal, wenn sie angefordert wird, neu instanziert.
n2n\model\RequestScoped Klasse wird pro Request nur einmal instanziert. Es wird immer dieselbe Instanz ausgeliefert.
n2n\model\SessionScoped Klasse wird pro Session einmal instanziert. Das Objekt wird serialisiert in der Session abgelegt und für den nächsten Request derselben Session wiederverwendet.
n2n\model\ApplicationScoped Klasse wird für die gesamte Applikation nur einmal instanziert. Das Objekt wird serialisiert in das var-Verzeichnis abgelegt und für alle zukünftigen Requests wiederverwendet.

Ein gutes Beispiel ist ein fiktives ArticleDao, das die Schnittstelle zur Datenbank implementiert. Es reicht, wenn diese Klasse nur einmal pro Request instanziert wird, auch wenn sie mehrfach verwendet werden sollte. Deshalb markieren wir sie als RequestScoped:

class ArticleDao implements RequestScoped {
    private $em;
    
    private function _init(EntityManager $em) {
        $this->em = $em;
    }
    
    public function getArticles() {
        return $this->em->createSimpleCriteria(Article::getClass(), null,
                array('id' => 'DESC'))->fetchArray();
    }
    
    public function getArticleById($id) {
        return $this->em->find(Article::getClass(), $id);
    }    
}

Das ArticleDao kannst du dir nun zum Beispiel in einem Controller über eine magische Methode (z. B. _init()) übergeben lassen:

class ExampleController extends ControllerAdapter {
    private $articleDao;
    
    private function _init(ArticleDao $articleDao) {
        $this->articleDao = $articleDao;
    }

Session Scoped

In RequestScoped-Klassen kannst du einzelne Properties mit der Annotation n2n\model\annotation\AnnoSessionScoped  markieren. Dies hat zur Folge, dass die Werte dieser Properties in die Session gespeichert und für den nächsten Request derselben Session erhalten bleiben. Die Werte werden dabei serialisiert.

class ExampleModel implements RequestScoped {
    private static function _annos(AnnoInit $ai) {
        $as->p('foo', new AnnoSessionScoped());
    }
    
    private $foo;
    private $bar;

Der Wert von $foo bleibt für den nächsten Aufruf derselben Session erhalten.

Nutzt du das Interface SessionScoped, wird das Objekt in der Session zwischengespeichert. Hierzu wird das Objekt serialisiert. SessionScoped-Klassen müssen darum die magischen Methoden _onSerialize() und _onUnserialize() implementieren.

class ExampleModel implements SessionScoped {
    private $foo;
    private $em;
    
    private function _init(EntityManager $em) {
        $this->em = $em;
    }
    
    private function _onSerialize() {
        $this->em = null;
    }
    
    private function _onUnserialize(EntityManager $em) {
        $this->em = $em;
    }

Wird die Klasse das erste Mal instanziert, wird _init() aufgerufen. Wird das Objekt aus der Session geladen, wird nur noch _onUnserialize() ausgeführt. _onSerialize() wird immer aufgerufen, bevor das Objekt serialisiert und in die Session gespeichert wird. In diesem Beispiel werden die Methoden genutzt, um bei jedem Request den aktuellen EntityManager zu holen und ihn danach wieder auf null zu setzen. Damit verhindern wir, dass der EntityManager serialisiert wird.

Da in PHP alle Objekte serialisiert werden können, kann es schnell passieren, dass Objekte ungewollt serialisiert werden. Diese können Referenzen auf andere Objekte enthalten, die dann ebenfalls serialisiert werden.

Application Scoped

n2n setzt den "Application Scope" auf dieselbe Weise wie den "Session Scope" um, nur dass die serialisierten Werte (Objekte sowie Property-Werte) nicht in der Session, sondern im var-Verzeichnis abgespeichert werden. Deshalb müssen auch für ApplicationScoped-Klassen _onSerialize() und _onUnserialize() implementiert werden. Mit der Annotation n2n\model\annotation\AnnoApplicationScoped kannst du in RequestScoped- und SessionScoped-Klassen auch einzelne Properties für den "Application Scope" markieren.

Du musst allerdings beachten, dass es nicht möglich ist, den "Application Scope" "threadsafe" zu machen. Änderungen können also verloren gehen. Du solltest sowieso verhindern, dass sich Werte oder Objekte, die "application scoped" sind, öfters verändern, da sich dies negativ auf die Performance auswirken kann. Der "Application Scope" eignet sich vorderhand, um Daten zwischenzuspeichern, die länger nicht aktualisiert werden müssen (z.B. einen Twitter- oder Facebook-Feed).
« Dependency Injections Formulare »

comments_title

post_login_to_create

questions_title