Lookupable
Objects of classes that you mark as "Lookupable" are managed by n2n in a central place and can also be used for dependency injections.
Lookupable
Use one of the following marker interfaces to mark a class as "lookupable". Objects of these classes are instantiated and centrally managed by n2n. You can request them via [Thomas, phpdoc]n2n\model\LookupableManager::lookup()[/Thomas, phpdoc] or have them passed to you via dependency injections.
| Interface | Behavior |
|---|---|
n2n\model\Lookupable | The class is instantiated anew every time it is requested. |
n2n\model\RequestScoped | The class is instantiated only once per request. The same instance is always returned. |
n2n\model\SessionScoped | The class is instantiated once per session. The object is stored serialized in the session and reused for the next request of the same session. |
n2n\model\ApplicationScoped | The class is instantiated only once for the entire application. The object is stored serialized in the var directory and reused for all future requests. |
A good example is a fictional ArticleDao that implements the interface to the database. It is sufficient if this class is instantiated only once per request, even if it is used multiple times. Therefore we mark it as 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);
}
}
You can now have the ArticleDao passed to you for example in a controller via a magic method (e.g. _init()):
class ExampleController extends ControllerAdapter {
private $articleDao;
private function _init(ArticleDao $articleDao) {
$this->articleDao = $articleDao;
}
Session Scoped
In RequestScoped classes you can mark individual properties with the annotation n2n\model\annotation\AnnoSessionScoped. As a result, the values of these properties are stored in the session and preserved for the next request of the same session. The values are serialized.
class ExampleModel implements RequestScoped {
private static function _annos(AnnoInit $ai) {
$as->p('foo', new AnnoSessionScoped());
}
private $foo;
private $bar;
The value of $foo is preserved for the next call of the same session.
If you use the interface SessionScoped, the object is cached in the session. For this the object is serialized. Therefore SessionScoped classes have to implement the magic methods _onSerialize() and _onUnserialize().
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;
}
The first time the class is instantiated, _init() is called. If the object is loaded from the session, only _onUnserialize() is executed. _onSerialize() is always called before the object is serialized and stored in the session. In this example the methods are used to fetch the current EntityManager on every request and set it back to null afterwards. This prevents the EntityManager from being serialized.
Attention
Since all objects can be serialized in PHP, it can quickly happen that objects are serialized unintentionally. These can contain references to other objects, which are then also serialized.
Application Scoped
n2n implements the "Application Scope" in the same way as the "Session Scope", except that the serialized values (objects as well as property values) are not stored in the session, but in the var directory. Therefore _onSerialize() and _onUnserialize() also have to be implemented for ApplicationScoped classes. With the annotation n2n\model\annotation\AnnoApplicationScoped you can also mark individual properties for the "Application Scope" in RequestScoped and SessionScoped classes.
Attention
However, you have to keep in mind that it is not possible to make the "Application Scope" "threadsafe". Changes can therefore get lost. In any case, you should prevent values or objects that are "application scoped" from changing frequently, as this can have a negative effect on performance. For the time being, the "Application Scope" is suitable for caching data that does not have to be updated for a longer time (e.g. a Twitter or Facebook feed).