vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/SaveSessionListener.php line 47

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\HttpKernel\EventListener;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  13. use Symfony\Component\HttpKernel\KernelEvents;
  14. /**
  15.  * Saves the session, in case it is still open, before sending the response/headers.
  16.  *
  17.  * This ensures several things in case the developer did not save the session explicitly:
  18.  *
  19.  *  * If a session save handler without locking is used, it ensures the data is available
  20.  *    on the next request, e.g. after a redirect. PHPs auto-save at script end via
  21.  *    session_register_shutdown is executed after fastcgi_finish_request. So in this case
  22.  *    the data could be missing the next request because it might not be saved the moment
  23.  *    the new request is processed.
  24.  *  * A locking save handler (e.g. the native 'files') circumvents concurrency problems like
  25.  *    the one above. But by saving the session before long-running things in the terminate event,
  26.  *    we ensure the session is not blocked longer than needed.
  27.  *  * When regenerating the session ID no locking is involved in PHPs session design. See
  28.  *    https://bugs.php.net/bug.php?id=61470 for a discussion. So in this case, the session must
  29.  *    be saved anyway before sending the headers with the new session ID. Otherwise session
  30.  *    data could get lost again for concurrent requests with the new ID. One result could be
  31.  *    that you get logged out after just logging in.
  32.  *
  33.  * This listener should be executed as one of the last listeners, so that previous listeners
  34.  * can still operate on the open session. This prevents the overhead of restarting it.
  35.  * Listeners after closing the session can still work with the session as usual because
  36.  * Symfonys session implementation starts the session on demand. So writing to it after
  37.  * it is saved will just restart it.
  38.  *
  39.  * @author Tobias Schultze <http://tobion.de>
  40.  */
  41. class SaveSessionListener implements EventSubscriberInterface
  42. {
  43.     public function onKernelResponse(FilterResponseEvent $event)
  44.     {
  45.         if (!$event->isMasterRequest()) {
  46.             return;
  47.         }
  48.         $session $event->getRequest()->getSession();
  49.         if ($session && $session->isStarted()) {
  50.             $session->save();
  51.             $event->getResponse()
  52.                 ->setPrivate()
  53.                 ->setMaxAge(0)
  54.                 ->headers->addCacheControlDirective('must-revalidate');
  55.         }
  56.     }
  57.     public static function getSubscribedEvents()
  58.     {
  59.         return array(
  60.             // low priority but higher than StreamedResponseListener
  61.             KernelEvents::RESPONSE => array(array('onKernelResponse', -1000)),
  62.         );
  63.     }
  64. }