3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Session\Storage
;
13 use IteratorAggregate
;
14 use Zend\Session\Exception
;
17 * Session storage in $_SESSION
19 * Replaces the $_SESSION superglobal with an ArrayObject that allows for
20 * property access, metadata storage, locking, and immutability.
22 abstract class AbstractSessionArrayStorage
implements
25 StorageInitializationInterface
30 * @param array|null $input
32 public function __construct($input = null)
34 // this is here for B.C.
45 public function init($input = null)
47 if ((null === $input) && isset($_SESSION)) {
49 if (is_object($input) && !$_SESSION instanceof \ArrayObject
) {
50 $input = (array) $input;
52 } elseif (null === $input) {
56 $this->setRequestAccessTime(microtime(true));
65 public function __get($key)
67 return $this->offsetGet($key);
77 public function __set($key, $value)
79 return $this->offsetSet($key, $value);
88 public function __isset($key)
90 return $this->offsetExists($key);
99 public function __unset($key)
101 return $this->offsetUnset($key);
109 public function __destruct()
120 public function offsetExists($key)
122 return isset($_SESSION[$key]);
131 public function offsetGet($key)
133 if (isset($_SESSION[$key])) {
134 return $_SESSION[$key];
144 * @param mixed $value
147 public function offsetSet($key, $value)
149 $_SESSION[$key] = $value;
158 public function offsetUnset($key)
160 unset($_SESSION[$key]);
168 public function count()
170 return count($_SESSION);
178 public function serialize()
180 return serialize($_SESSION);
186 * @param string $session
189 public function unserialize($session)
191 return unserialize($session);
197 * @return ArrayIterator
199 public function getIterator()
201 return new ArrayIterator($_SESSION);
205 * Load session object from an existing array
207 * Ensures $_SESSION is set to an instance of the object when complete.
209 * @param array $array
210 * @return SessionStorage
212 public function fromArray(array $array)
214 $ts = $this->getRequestAccessTime();
216 $this->setRequestAccessTime($ts);
222 * Mark object as isImmutable
224 * @return SessionStorage
226 public function markImmutable()
228 $_SESSION['_IMMUTABLE'] = true;
234 * Determine if this object is isImmutable
238 public function isImmutable()
240 return (isset($_SESSION['_IMMUTABLE']) && $_SESSION['_IMMUTABLE']);
244 * Lock this storage instance, or a key within it
246 * @param null|int|string $key
247 * @return ArrayStorage
249 public function lock($key = null)
252 $this->setMetadata('_READONLY', true);
256 if (isset($_SESSION[$key])) {
257 $this->setMetadata('_LOCKS', array($key => true));
264 * Is the object or key marked as locked?
266 * @param null|int|string $key
269 public function isLocked($key = null)
271 if ($this->isImmutable()) {
272 // isImmutable trumps all
277 // testing for global lock
278 return $this->getMetadata('_READONLY');
281 $locks = $this->getMetadata('_LOCKS');
282 $readOnly = $this->getMetadata('_READONLY');
284 if ($readOnly && !$locks) {
285 // global lock in play; all keys are locked
288 if ($readOnly && $locks) {
289 return array_key_exists($key, $locks);
292 // test for individual locks
297 return array_key_exists($key, $locks);
301 * Unlock an object or key marked as locked
303 * @param null|int|string $key
304 * @return ArrayStorage
306 public function unlock($key = null)
310 $this->setMetadata('_READONLY', false);
311 $this->setMetadata('_LOCKS', false);
316 $locks = $this->getMetadata('_LOCKS');
318 if (!$this->getMetadata('_READONLY')) {
321 $array = $this->toArray();
322 $keys = array_keys($array);
323 $locks = array_flip($keys);
324 unset($array, $keys);
327 if (array_key_exists($key, $locks)) {
329 $this->setMetadata('_LOCKS', $locks, true);
336 * Set storage metadata
338 * Metadata is used to store information about the data being stored in the
339 * object. Some example use cases include:
340 * - Setting expiry data
341 * - Maintaining access counts
342 * - localizing session storage
346 * @param mixed $value
347 * @param bool $overwriteArray Whether to overwrite or merge array values; by default, merges
348 * @return ArrayStorage
349 * @throws Exception\RuntimeException
351 public function setMetadata($key, $value, $overwriteArray = false)
353 if ($this->isImmutable()) {
354 throw new Exception\
RuntimeException(sprintf(
355 'Cannot set key "%s" as storage is marked isImmutable', $key
359 if (!isset($_SESSION['__ZF'])) {
360 $_SESSION['__ZF'] = array();
362 if (isset($_SESSION['__ZF'][$key]) && is_array($value)) {
363 if ($overwriteArray) {
364 $_SESSION['__ZF'][$key] = $value;
366 $_SESSION['__ZF'][$key] = array_replace_recursive($_SESSION['__ZF'][$key], $value);
369 if ((null === $value) && isset($_SESSION['__ZF'][$key])) {
370 $array = $_SESSION['__ZF'];
372 $_SESSION['__ZF'] = $array;
374 } elseif (null !== $value) {
375 $_SESSION['__ZF'][$key] = $value;
383 * Retrieve metadata for the storage object or a specific metadata key
385 * Returns false if no metadata stored, or no metadata exists for the given
388 * @param null|int|string $key
391 public function getMetadata($key = null)
393 if (!isset($_SESSION['__ZF'])) {
398 return $_SESSION['__ZF'];
401 if (!array_key_exists($key, $_SESSION['__ZF'])) {
405 return $_SESSION['__ZF'][$key];
409 * Clear the storage object or a subkey of the object
411 * @param null|int|string $key
412 * @return ArrayStorage
413 * @throws Exception\RuntimeException
415 public function clear($key = null)
417 if ($this->isImmutable()) {
418 throw new Exception\
RuntimeException('Cannot clear storage as it is marked immutable');
421 $this->fromArray(array());
426 if (!isset($_SESSION[$key])) {
431 unset($_SESSION[$key]);
433 // Clear key metadata
434 $this->setMetadata($key, null)
441 * Retrieve the request access time
445 public function getRequestAccessTime()
447 return $this->getMetadata('_REQUEST_ACCESS_TIME');
451 * Set the request access time
454 * @return ArrayStorage
456 protected function setRequestAccessTime($time)
458 $this->setMetadata('_REQUEST_ACCESS_TIME', $time);
464 * Cast the object to an array
466 * @param bool $metaData Whether to include metadata
469 public function toArray($metaData = false)
471 if (isset($_SESSION)) {
481 if (isset($values['__ZF'])) {
482 unset($values['__ZF']);