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

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. /**
  12.  * This abstract session handler provides a generic implementation
  13.  * of the PHP 7.0 SessionUpdateTimestampHandlerInterface,
  14.  * enabling strict and lazy session handling.
  15.  *
  16.  * @author Nicolas Grekas <p@tchwork.com>
  17.  */
  18. abstract class AbstractSessionHandler implements \SessionHandlerInterface\SessionUpdateTimestampHandlerInterface
  19. {
  20.     private $sessionName;
  21.     private $prefetchId;
  22.     private $prefetchData;
  23.     private $newSessionId;
  24.     private $igbinaryEmptyData;
  25.     /**
  26.      * {@inheritdoc}
  27.      */
  28.     public function open($savePath$sessionName)
  29.     {
  30.         $this->sessionName $sessionName;
  31.         if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) {
  32.             header(sprintf('Cache-Control: max-age=%d, private, must-revalidate'60 * (int) ini_get('session.cache_expire')));
  33.         }
  34.         return true;
  35.     }
  36.     /**
  37.      * @param string $sessionId
  38.      *
  39.      * @return string
  40.      */
  41.     abstract protected function doRead($sessionId);
  42.     /**
  43.      * @param string $sessionId
  44.      * @param string $data
  45.      *
  46.      * @return bool
  47.      */
  48.     abstract protected function doWrite($sessionId$data);
  49.     /**
  50.      * @param string $sessionId
  51.      *
  52.      * @return bool
  53.      */
  54.     abstract protected function doDestroy($sessionId);
  55.     /**
  56.      * {@inheritdoc}
  57.      */
  58.     public function validateId($sessionId)
  59.     {
  60.         $this->prefetchData $this->read($sessionId);
  61.         $this->prefetchId $sessionId;
  62.         return '' !== $this->prefetchData;
  63.     }
  64.     /**
  65.      * {@inheritdoc}
  66.      */
  67.     public function read($sessionId)
  68.     {
  69.         if (null !== $this->prefetchId) {
  70.             $prefetchId $this->prefetchId;
  71.             $prefetchData $this->prefetchData;
  72.             $this->prefetchId $this->prefetchData null;
  73.             if ($prefetchId === $sessionId || '' === $prefetchData) {
  74.                 $this->newSessionId '' === $prefetchData $sessionId null;
  75.                 return $prefetchData;
  76.             }
  77.         }
  78.         $data $this->doRead($sessionId);
  79.         $this->newSessionId '' === $data $sessionId null;
  80.         if (\PHP_VERSION_ID 70000) {
  81.             $this->prefetchData $data;
  82.         }
  83.         return $data;
  84.     }
  85.     /**
  86.      * {@inheritdoc}
  87.      */
  88.     public function write($sessionId$data)
  89.     {
  90.         if (\PHP_VERSION_ID 70000 && $this->prefetchData) {
  91.             $readData $this->prefetchData;
  92.             $this->prefetchData null;
  93.             if ($readData === $data) {
  94.                 return $this->updateTimestamp($sessionId$data);
  95.             }
  96.         }
  97.         if (null === $this->igbinaryEmptyData) {
  98.             // see https://github.com/igbinary/igbinary/issues/146
  99.             $this->igbinaryEmptyData \function_exists('igbinary_serialize') ? igbinary_serialize([]) : '';
  100.         }
  101.         if ('' === $data || $this->igbinaryEmptyData === $data) {
  102.             return $this->destroy($sessionId);
  103.         }
  104.         $this->newSessionId null;
  105.         return $this->doWrite($sessionId$data);
  106.     }
  107.     /**
  108.      * {@inheritdoc}
  109.      */
  110.     public function destroy($sessionId)
  111.     {
  112.         if (\PHP_VERSION_ID 70000) {
  113.             $this->prefetchData null;
  114.         }
  115.         if (!headers_sent() && filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN)) {
  116.             if (!$this->sessionName) {
  117.                 throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.'\get_class($this)));
  118.             }
  119.             $sessionCookie sprintf(' %s='urlencode($this->sessionName));
  120.             $sessionCookieWithId sprintf('%s%s;'$sessionCookieurlencode($sessionId));
  121.             $sessionCookieFound false;
  122.             $otherCookies = [];
  123.             foreach (headers_list() as $h) {
  124.                 if (!== stripos($h'Set-Cookie:')) {
  125.                     continue;
  126.                 }
  127.                 if (11 === strpos($h$sessionCookie11)) {
  128.                     $sessionCookieFound true;
  129.                     if (11 !== strpos($h$sessionCookieWithId11)) {
  130.                         $otherCookies[] = $h;
  131.                     }
  132.                 } else {
  133.                     $otherCookies[] = $h;
  134.                 }
  135.             }
  136.             if ($sessionCookieFound) {
  137.                 header_remove('Set-Cookie');
  138.                 foreach ($otherCookies as $h) {
  139.                     header($hfalse);
  140.                 }
  141.             } else {
  142.                 setcookie($this->sessionName''0ini_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));
  143.             }
  144.         }
  145.         return $this->newSessionId === $sessionId || $this->doDestroy($sessionId);
  146.     }
  147. }