annotate vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@14 1 <?php
Chris@14 2
Chris@14 3 /*
Chris@14 4 * This file is part of the Symfony package.
Chris@14 5 *
Chris@14 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@14 7 *
Chris@14 8 * For the full copyright and license information, please view the LICENSE
Chris@14 9 * file that was distributed with this source code.
Chris@14 10 */
Chris@14 11
Chris@14 12 namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
Chris@14 13
Chris@14 14 /**
Chris@14 15 * This abstract session handler provides a generic implementation
Chris@14 16 * of the PHP 7.0 SessionUpdateTimestampHandlerInterface,
Chris@14 17 * enabling strict and lazy session handling.
Chris@14 18 *
Chris@14 19 * @author Nicolas Grekas <p@tchwork.com>
Chris@14 20 */
Chris@14 21 abstract class AbstractSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
Chris@14 22 {
Chris@14 23 private $sessionName;
Chris@14 24 private $prefetchId;
Chris@14 25 private $prefetchData;
Chris@14 26 private $newSessionId;
Chris@14 27 private $igbinaryEmptyData;
Chris@14 28
Chris@14 29 /**
Chris@14 30 * {@inheritdoc}
Chris@14 31 */
Chris@14 32 public function open($savePath, $sessionName)
Chris@14 33 {
Chris@14 34 $this->sessionName = $sessionName;
Chris@14 35 if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) {
Chris@14 36 header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) ini_get('session.cache_expire')));
Chris@14 37 }
Chris@14 38
Chris@14 39 return true;
Chris@14 40 }
Chris@14 41
Chris@14 42 /**
Chris@14 43 * @param string $sessionId
Chris@14 44 *
Chris@14 45 * @return string
Chris@14 46 */
Chris@14 47 abstract protected function doRead($sessionId);
Chris@14 48
Chris@14 49 /**
Chris@14 50 * @param string $sessionId
Chris@14 51 * @param string $data
Chris@14 52 *
Chris@14 53 * @return bool
Chris@14 54 */
Chris@14 55 abstract protected function doWrite($sessionId, $data);
Chris@14 56
Chris@14 57 /**
Chris@14 58 * @param string $sessionId
Chris@14 59 *
Chris@14 60 * @return bool
Chris@14 61 */
Chris@14 62 abstract protected function doDestroy($sessionId);
Chris@14 63
Chris@14 64 /**
Chris@14 65 * {@inheritdoc}
Chris@14 66 */
Chris@14 67 public function validateId($sessionId)
Chris@14 68 {
Chris@14 69 $this->prefetchData = $this->read($sessionId);
Chris@14 70 $this->prefetchId = $sessionId;
Chris@14 71
Chris@14 72 return '' !== $this->prefetchData;
Chris@14 73 }
Chris@14 74
Chris@14 75 /**
Chris@14 76 * {@inheritdoc}
Chris@14 77 */
Chris@14 78 public function read($sessionId)
Chris@14 79 {
Chris@14 80 if (null !== $this->prefetchId) {
Chris@14 81 $prefetchId = $this->prefetchId;
Chris@14 82 $prefetchData = $this->prefetchData;
Chris@14 83 $this->prefetchId = $this->prefetchData = null;
Chris@14 84
Chris@14 85 if ($prefetchId === $sessionId || '' === $prefetchData) {
Chris@14 86 $this->newSessionId = '' === $prefetchData ? $sessionId : null;
Chris@14 87
Chris@14 88 return $prefetchData;
Chris@14 89 }
Chris@14 90 }
Chris@14 91
Chris@14 92 $data = $this->doRead($sessionId);
Chris@14 93 $this->newSessionId = '' === $data ? $sessionId : null;
Chris@14 94 if (\PHP_VERSION_ID < 70000) {
Chris@14 95 $this->prefetchData = $data;
Chris@14 96 }
Chris@14 97
Chris@14 98 return $data;
Chris@14 99 }
Chris@14 100
Chris@14 101 /**
Chris@14 102 * {@inheritdoc}
Chris@14 103 */
Chris@14 104 public function write($sessionId, $data)
Chris@14 105 {
Chris@14 106 if (\PHP_VERSION_ID < 70000 && $this->prefetchData) {
Chris@14 107 $readData = $this->prefetchData;
Chris@14 108 $this->prefetchData = null;
Chris@14 109
Chris@14 110 if ($readData === $data) {
Chris@14 111 return $this->updateTimestamp($sessionId, $data);
Chris@14 112 }
Chris@14 113 }
Chris@14 114 if (null === $this->igbinaryEmptyData) {
Chris@14 115 // see https://github.com/igbinary/igbinary/issues/146
Chris@17 116 $this->igbinaryEmptyData = \function_exists('igbinary_serialize') ? igbinary_serialize([]) : '';
Chris@14 117 }
Chris@14 118 if ('' === $data || $this->igbinaryEmptyData === $data) {
Chris@14 119 return $this->destroy($sessionId);
Chris@14 120 }
Chris@14 121 $this->newSessionId = null;
Chris@14 122
Chris@14 123 return $this->doWrite($sessionId, $data);
Chris@14 124 }
Chris@14 125
Chris@14 126 /**
Chris@14 127 * {@inheritdoc}
Chris@14 128 */
Chris@14 129 public function destroy($sessionId)
Chris@14 130 {
Chris@14 131 if (\PHP_VERSION_ID < 70000) {
Chris@14 132 $this->prefetchData = null;
Chris@14 133 }
Chris@17 134 if (!headers_sent() && filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN)) {
Chris@14 135 if (!$this->sessionName) {
Chris@17 136 throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', \get_class($this)));
Chris@14 137 }
Chris@14 138 $sessionCookie = sprintf(' %s=', urlencode($this->sessionName));
Chris@14 139 $sessionCookieWithId = sprintf('%s%s;', $sessionCookie, urlencode($sessionId));
Chris@14 140 $sessionCookieFound = false;
Chris@17 141 $otherCookies = [];
Chris@14 142 foreach (headers_list() as $h) {
Chris@14 143 if (0 !== stripos($h, 'Set-Cookie:')) {
Chris@14 144 continue;
Chris@14 145 }
Chris@14 146 if (11 === strpos($h, $sessionCookie, 11)) {
Chris@14 147 $sessionCookieFound = true;
Chris@14 148
Chris@14 149 if (11 !== strpos($h, $sessionCookieWithId, 11)) {
Chris@14 150 $otherCookies[] = $h;
Chris@14 151 }
Chris@14 152 } else {
Chris@14 153 $otherCookies[] = $h;
Chris@14 154 }
Chris@14 155 }
Chris@14 156 if ($sessionCookieFound) {
Chris@14 157 header_remove('Set-Cookie');
Chris@14 158 foreach ($otherCookies as $h) {
Chris@14 159 header($h, false);
Chris@14 160 }
Chris@14 161 } else {
Chris@17 162 setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN), filter_var(ini_get('session.cookie_httponly'), FILTER_VALIDATE_BOOLEAN));
Chris@14 163 }
Chris@14 164 }
Chris@14 165
Chris@14 166 return $this->newSessionId === $sessionId || $this->doDestroy($sessionId);
Chris@14 167 }
Chris@14 168 }