vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php line 69

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
  11. use Symfony\Component\HttpFoundation\Session\SessionUtils;
  12. /**
  13.  * This abstract session handler provides a generic implementation
  14.  * of the PHP 7.0 SessionUpdateTimestampHandlerInterface,
  15.  * enabling strict and lazy session handling.
  16.  *
  17.  * @author Nicolas Grekas <p@tchwork.com>
  18.  */
  19. abstract class AbstractSessionHandler implements \SessionHandlerInterface\SessionUpdateTimestampHandlerInterface
  20. {
  21.     private string $sessionName;
  22.     private string $prefetchId;
  23.     private string $prefetchData;
  24.     private ?string $newSessionId null;
  25.     private string $igbinaryEmptyData;
  26.     public function open(string $savePathstring $sessionName): bool
  27.     {
  28.         $this->sessionName $sessionName;
  29.         if (!headers_sent() && !\ini_get('session.cache_limiter') && '0' !== \ini_get('session.cache_limiter')) {
  30.             header(sprintf('Cache-Control: max-age=%d, private, must-revalidate'60 * (int) \ini_get('session.cache_expire')));
  31.         }
  32.         return true;
  33.     }
  34.     abstract protected function doRead(string $sessionId): string;
  35.     abstract protected function doWrite(string $sessionIdstring $data): bool;
  36.     abstract protected function doDestroy(string $sessionId): bool;
  37.     public function validateId(string $sessionId): bool
  38.     {
  39.         $this->prefetchData $this->read($sessionId);
  40.         $this->prefetchId $sessionId;
  41.         return '' !== $this->prefetchData;
  42.     }
  43.     public function read(string $sessionId): string
  44.     {
  45.         if (isset($this->prefetchId)) {
  46.             $prefetchId $this->prefetchId;
  47.             $prefetchData $this->prefetchData;
  48.             unset($this->prefetchId$this->prefetchData);
  49.             if ($prefetchId === $sessionId || '' === $prefetchData) {
  50.                 $this->newSessionId '' === $prefetchData $sessionId null;
  51.                 return $prefetchData;
  52.             }
  53.         }
  54.         $data $this->doRead($sessionId);
  55.         $this->newSessionId '' === $data $sessionId null;
  56.         return $data;
  57.     }
  58.     public function write(string $sessionIdstring $data): bool
  59.     {
  60.         // see https://github.com/igbinary/igbinary/issues/146
  61.         $this->igbinaryEmptyData ??= \function_exists('igbinary_serialize') ? igbinary_serialize([]) : '';
  62.         if ('' === $data || $this->igbinaryEmptyData === $data) {
  63.             return $this->destroy($sessionId);
  64.         }
  65.         $this->newSessionId null;
  66.         return $this->doWrite($sessionId$data);
  67.     }
  68.     public function destroy(string $sessionId): bool
  69.     {
  70.         if (!headers_sent() && filter_var(\ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN)) {
  71.             if (!isset($this->sessionName)) {
  72.                 throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', static::class));
  73.             }
  74.             $cookie SessionUtils::popSessionCookie($this->sessionName$sessionId);
  75.             /*
  76.              * We send an invalidation Set-Cookie header (zero lifetime)
  77.              * when either the session was started or a cookie with
  78.              * the session name was sent by the client (in which case
  79.              * we know it's invalid as a valid session cookie would've
  80.              * started the session).
  81.              */
  82.             if (null === $cookie || isset($_COOKIE[$this->sessionName])) {
  83.                 $params session_get_cookie_params();
  84.                 unset($params['lifetime']);
  85.                 setcookie($this->sessionName''$params);
  86.             }
  87.         }
  88.         return $this->newSessionId === $sessionId || $this->doDestroy($sessionId);
  89.     }
  90. }