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.
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.
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.