| 3 | | Your typical PHP web application will store a lot of data in the HTTP session. The problem with most applications is, that they store all session information in arrays, or loosely typed scalar values and are loosing all benefits of OO development. The [source:trunk/src/main/php/net/stubbles/ipo/session/resourcemanager/stubSessionResourceManager.php stubSessionResourceManager] tries to solve this problem by providing an easy to use API for storing objects in the session. The concept of the session resource manager has been borrowed from the [http://pustefix.oss.schlund.de Pustefix framework]. |
| 4 | | |
| 5 | | == What is a session resource? == |
| 6 | | |
| 7 | | A session resource is an interface to any kind of data, that is persisted between all requests of the same user session. In Stubbles, any object can be such a session resource. The session resource will be managed completely by the [source:trunk/src/main/php/net/stubbles/ipo/session/resourcemanager/stubSessionResourceManager.php stubSessionResourceManager]. That means that the session resource manager takes care of creating and persisting the resource for you. As a session resource is only an interface your data, your application does not even have to know about the concrete implementation of the resources it uses. |
| 8 | | |
| 9 | | To create a session resource, you have to follow these steps: |
| 10 | | 1. Create a new interface that extends the [source:trunk/src/main/php/net/stubbles/ipo/session/resourcemanager/stubSessionResource.php stubSessionResource] interface. This currently is a marker interface, that extends the {{{stubSerializable}}} interface. |
| 11 | | 2. Add any number of methods to this interface. |
| 12 | | 3. Create a new class that implements your new session resource. |
| 13 | | |
| 14 | | A basic example for a session resource, that acts as a counter could be the following interface with its example implementation: |
| 15 | | |
| 16 | | {{{ |
| 17 | | #!php |
| 18 | | <?php |
| 19 | | /** |
| 20 | | * Interface for the session resource |
| 21 | | */ |
| 22 | | interface MyResource extends stubSessionResource { |
| 23 | | /** |
| 24 | | * returns the current count value |
| 25 | | * |
| 26 | | * @return int |
| 27 | | */ |
| 28 | | public function getCount(); |
| 29 | | |
| 30 | | /** |
| 31 | | * increments the counter |
| 32 | | */ |
| 33 | | public function incrementCount(); |
| 34 | | } |
| 35 | | |
| 36 | | /** |
| 37 | | * Implementation for the resource |
| 38 | | */ |
| 39 | | class MyResourceImpl extends stubSerializableObject implements MyResource { |
| 40 | | /** |
| 41 | | * the counter |
| 42 | | * |
| 43 | | * @var int |
| 44 | | */ |
| 45 | | protected $count; |
| 46 | | |
| 47 | | /** |
| 48 | | * constructor |
| 49 | | */ |
| 50 | | public function __construct() |
| 51 | | { |
| 52 | | $this->count = 0; |
| 53 | | } |
| 54 | | |
| 55 | | /** |
| 56 | | * returns the current count value |
| 57 | | * |
| 58 | | * @return int |
| 59 | | */ |
| 60 | | public function getCount() |
| 61 | | { |
| 62 | | return $this->count; |
| 63 | | } |
| 64 | | |
| 65 | | /** |
| 66 | | * increments the counter |
| 67 | | * |
| 68 | | */ |
| 69 | | public function incrementCount() |
| 70 | | { |
| 71 | | $this->count++; |
| 72 | | } |
| 73 | | } |
| 74 | | ?> |
| 75 | | }}} |
| 76 | | |
| 77 | | Both, the interface and the implementation, are part of the Stubbles distribution and located in the [source:browser/trunk/src/main/php/org/stubbles/examples/resources examples]. |
| 78 | | |
| 79 | | == Configuring session resources == |
| 80 | | |
| 81 | | Session resources are configured via the [source:trunk/config/xml/session-resources.xml session-resources.xml] configuration file. In this file, you need to register all interfaces that you want the resource manager to expose as well as the implementations you want to use. |
| 82 | | |
| 83 | | The configuration to register the above mentioned resource has to be done like this: |
| 84 | | |
| 85 | | {{{ |
| 86 | | #!xml |
| 87 | | <?xml version="1.0" encoding="iso-8859-1"?> |
| 88 | | <xj:configuration |
| 89 | | xmlns:xj="http://xjconf.net/XJConf" |
| 90 | | xmlns:cfg="http://stubbles.net/util/XJConf" |
| 91 | | xmlns="http://stubbles.net/ipo/session-resources"> |
| 92 | | <resources> |
| 93 | | <resource class="org::stubbles::examples::resources::MyResourceImpl"> |
| 94 | | <implements>org::stubbles::examples::resources::MyResource</implements> |
| 95 | | </resource> |
| 96 | | </resources> |
| 97 | | </xj:configuration> |
| 98 | | }}} |
| 99 | | |
| 100 | | Inside the {{{<resources/>}}} tag, you may nest as many {{{<resource/>}}} tags as you want session resource implementations to be registered. Each implementation needs at least one {{{<implements/>}}} tag, but you may nest as many of the {{{<implements/>}}} tags as you like. |
| 101 | | |
| 102 | | When configuring the session resources, make sure to follow these rules: |
| 103 | | * All classes must implement the interfaces specified with the {{{<implements/>}}} tags. |
| 104 | | * All interfaces must extend the {{{stubSessionResource}}} interface. |
| 105 | | |
| 106 | | == Accessing session resources == |
| 107 | | |
| 108 | | To access the session resources you configured, you will need to create a new instance of the {{{stubSessionResourceManager}}}, parse the {{{session-resources.xml}}} configuration file and configure the resource manager according to this file. Luckily, there already is an interceptor which will take care of these steps during the setup phase of your application. |
| 109 | | |
| 110 | | To enabe the session resource manager, add the [source:trunk/src/main/php/net/stubbles/ipo/session/resourcemanager/stubSessionResourceManagerPreInterceptor.php stubSessionResourceManagerPreInterceptor] to the [source:trunk/config/xml/interceptors.xml interceptors.xml] configuration file. This interceptor will configure the session resource manager and store it in the registry, where you can access it via the key {{{net.stubbles.ipo.session.resourcemanager.stubSessionResourceManager}}}. |
| 111 | | |
| 112 | | To fetch the session resource manager and access a configured resource, use the following code: |
| 113 | | |
| 114 | | {{{ |
| 115 | | #!php |
| 116 | | <?php |
| 117 | | $resourceManager = stubRegistry::get('net.stubbles.ipo.session.resourcemanager.stubSessionResourceManager'); |
| 118 | | $resource = $resourceManager->getResource('org.stubbles.examples.resources.MyResource'); |
| 119 | | $resource->incrementCount(); |
| 120 | | echo $resource->getCount(); |
| 121 | | ?> |
| 122 | | }}} |
| 123 | | |
| 124 | | Now let us take a look, at what happens here: |
| 125 | | |
| 126 | | 1. If the resource {{{org::stubbles::examples::resources::MyResource}}} is requested for the first time, the session resource manager creates a new instance of the specified implementation ({{{org::stubbles::examples::resources::MyResourceImpl}}} and returns it. |
| 127 | | 1. At the end of the request, the instance is serialized to the session. |
| 128 | | 1. If the resource is requested in any subsequent request, the session resource manager will unserialize the resource which had been created in the previous request. |
| 129 | | 1. If the resource is not requested, it will not be unserialized in the subsequent requests. |
| 130 | | |
| 131 | | == Advantages of using the session resource manager == |
| 132 | | |
| 133 | | Using the session resource manager has several advantages over handling the session in a traditional way: |
| 134 | | |
| 135 | | * You can be sure, that a session key is not used twice by different parts of your application. With a standard session, you get the same problems that you get with the use of global variables. |
| 136 | | * The session resource manager adds an additional level of abstraction to your application, as your business logic only works with interfaces to the date in your session and not with the actual data. |
| 137 | | * The objects will only be unserialized if requested, you do not have to load all classes on every page as you would have to when adding objects to {{{$_SESSION}}}. |
| 138 | | * The session resource manager converts all classes to ''singletons in the session scope'' without the need for additional code in the class itself. |
| 139 | | |
| 140 | | == Session resources and Inversion of Control == |
| 141 | | |
| 142 | | The session resource manager easily interacts with the [wiki:Docs/IOC Inversion of Control container] provided by Stubbles. If you are not familiar with the IoC features, please refer to the documentation of this feature, before you continue reading. |
| 143 | | |
| 144 | | If you want to add bindings for all of your configured resources, you only need to pass the {{{stubBinder}}} instance to the {{{registerBindings()}}} method of the {{{stubSessionResourceManager}}}: |
| 145 | | |
| 146 | | {{{ |
| 147 | | #!php |
| 148 | | <?php |
| 149 | | $binder = new stubBinder(); |
| 150 | | $resoucerManager = new stubSessionResourceManager($session); |
| 151 | | $resourceManager->registerBindings($binder); |
| 152 | | ?> |
| 153 | | }}} |
| 154 | | |
| 155 | | You can now inject all of the configured resources in any of your classes, that are created using the {{{stubInjector}}}. On huge advantage is, that the page elements that handle the requests will automatically receive the resources they require. |
| 156 | | |
| 157 | | The following example illustrates this feature: |
| 158 | | |
| 159 | | {{{ |
| 160 | | #!php |
| 161 | | <?php |
| 162 | | /** |
| 163 | | * Simple page element for demonstration purposes |
| 164 | | */ |
| 165 | | class MyPageElement extends stubAbstractPageElement implements stubXMLPageElement { |
| 166 | | /** |
| 167 | | * A resource that will be injected |
| 168 | | * |
| 169 | | * @var Myresource |
| 170 | | */ |
| 171 | | private $resource; |
| 172 | | |
| 173 | | /** |
| 174 | | * Set the resource. |
| 175 | | * |
| 176 | | * This will be done automatically via dependency injection. |
| 177 | | * |
| 178 | | * @Inject |
| 179 | | * @param MyResource $resource |
| 180 | | */ |
| 181 | | public function setMyResource(MyResource $resource) { |
| 182 | | $this->resource = $resource; |
| 183 | | } |
| 184 | | |
| 185 | | /** |
| 186 | | * processes the page element |
| 187 | | * |
| 188 | | * @return mixed |
| 189 | | */ |
| 190 | | public function process() |
| 191 | | { |
| 192 | | $this->resource->incrementCount(); |
| 193 | | return array(); |
| 194 | | } |
| 195 | | |
| 196 | | /** |
| 197 | | * returns a list of form values |
| 198 | | * |
| 199 | | * @return array<string,string> |
| 200 | | */ |
| 201 | | public function getFormValues() { |
| 202 | | return array(); |
| 203 | | } |
| 204 | | } |
| 205 | | ?> |
| 206 | | }}} |
| 207 | | |
| 208 | | == Using session resources with the XML/XSL view engine == |
| 209 | | |
| 210 | | The [wiki:Docs/MVC/ViewEngines/XSL XML/XSL view engine] also provides integration with the session resource manager. It allows you to add any session resource directly to the DOM tree. Refer to the [wiki:Docs/MVC/ViewEngines/XSL/PageConfiguration#Resources documenation of the view engine] for more information. |
| | 3 | The session resource manager was part of Stubbles until release 0.6.0. With release 0.7.0 it was superseded with the [wiki:Docs/IOC#Thesessionscope inversion of control container's session scope]. |