Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Possible PdoSessionStorage issue #2591

Closed
@mmucklo

Description

@mmucklo

We seem to have encountered a case where PdoSessionStorage, or a similar class may not save to DB / storage at the end of the request.

We've worked around it, however I'm posting this issue at the request of someone on the newsgroup.

We have a derivative of NativeSessionStorage who's start() method is identical (+/- whitespace) to PdoSessionStorage.php

    /**
     * Starts the session.
     */
    public function start()
    {
        if (self::$sessionStarted) {
            return;
        }

        // use this object as the session handler
        session_set_save_handler(
            array($this, 'sessionOpen'),
            array($this, 'sessionClose'),
            array($this, 'sessionRead'),
            array($this, 'sessionWrite'),
            array($this, 'sessionDestroy'),
            array($this, 'sessionGC')
        );

        parent::start();
    }

We then more or less implement sessionWrite, sessionRead, etc.

The problem is that sessionWrite in certain circumstances doesn't seem to be called at the end of the request, resulting in variables not written to our session storage.

What we see is :

  1. PdoSessionStorage(or Equivalent)->sessionWrite() (called by PHP save_handler routine)
  2. Session->__destruct
  3. Calls Session->save()
  4. Calls PdoSessionStorage(NativeSessionStorage)->write()
  5. $_SESSION updated
  6. end of request. (updated $_SESSION never saved)

What actually needs to happen:

  1. Session->__destruct
  2. Calls Session->save()
  3. Calls PdoSessionStorage(NativeSessionStorage)->write()
  4. $_SESSION updated
  5. PdoSessionStorage(or Equivalent)->sessionWrite()
  6. end of request.

We've hacked around it, but I think the problem is that PHP is calling the save handler before __destruct, and doesn't call it afterwards as perhaps it's cleared or something (don't know internally the order of things).

Our hack extends Session and implementing a __destruct such as below, and using this as the session handler instead by overriding it in a custom session.xml file similar to this:

namespace Us\OurBundle\Session;

class HackedSession
    extends \Symfony\Component\HttpFoundation\Session
{
    public function __destruct()
    {
        parent::__destruct();
        if (true === $this->started && !$this->closed) {
            if(method_exists($this->storage, 'sessionWrite'));
            $this->storage->sessionWrite($this->getId(), session_encode());
        }
    }
}

session.xml:

    <parameters>
                 <!-- ... -->
        <parameter key="session.class">Us\OurBundle\Session\HackedSession</parameter>
    </parameters>

Then load this session.xml under our DependencyInjection class using $loader->load...

Anyway, I'm not sure this is the best way to fix the problem but would appreciate input.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions