Development

#3647 (Sessions cannot be created / fix?)

You must first sign up to be able to contribute.

Ticket #3647 (closed enhancement: fixed)

Opened 7 years ago

Last modified 6 years ago

Sessions cannot be created / fix?

Reported by: joaocorreia Assigned to: fabien
Priority: major Milestone: 1.1.0
Component: other Version: 1.1.0 DEV
Keywords: sfMySQLSessionStorage, Session Cc:
Qualification: Unreviewed

Description

Revision: 9335. When using a remote MySQL server for a webapp:

lib/storage/sfMySQLSessionStorage.class.php

generates an error:

[sfDatabaseException] stack trace

  • at () in SF_SYMFONY_LIB_DIR/storage/sfMySQLSessionStorage.class.php line 126 ...
    1. } 124.
    2. // can't create record
    3. throw new sfDatabaseException(sprintf('% cannot create new record for id "%s" (%s).', get_class($this), $id, mysql_error()));
    4. }
    5. }

129.

  • at sfMySQLSessionStorage->sessionRead('2ad2d4e53695d47bee5a9a926a28a5bf') in n/a line n/a ...
  • at session_start() in SF_SYMFONY_LIB_DIR/storage/sfDatabaseSessionStorage.class.php line 72 ...

If at line 172 and 183 you add ->getResource() to $this->db it starts working. $this->db->getResource() instead of $this->db !

If you add ->getResource() you the unit test will fail but symfony works. If you remove Symfony will not work and unit test will pass.

Change History

05/28/08 11:31:45 changed by FabianLange

the explanation given by joaocorreia is incomplete. As we found out

$this->db

works okay for local connections, while

$this->db->getResource()

is required for remote connections.

I am unsure where this really originates. my asumption is that the $this->db = $db->getConnection() returns two different and incompatible results. perhaps we should add a check there if we need to retrieve the Resource still?

06/10/08 13:12:21 changed by FabianLange

this is also described in #3721.

I feel a bit uncomfortable to fix this in this class, as the error orriginates from the sfDatabaseSession storage. It violates implicit API, as it seems

$this->db
}}
can be two different things

06/15/08 09:17:47 changed by FabianLange

  • milestone set to 1.1.0.

another duplicate is #3749 i am setting final as milestone because due to the number of bugs reported this has to be fixed

06/16/08 11:43:47 changed by paulo_graca

I've tested this by creating a new project and here are some errors. They may contibute for an anwser...

Warning: mysql_real_escape_string() expects parameter 2 to be resource, object given in /var/symfony/branches/1.1/lib/storage/sfMySQLSessionStorage.class.php on line 183

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /var/symfony/branches/1.1/lib/storage/sfMySQLSessionStorage.class.php:183) in /var/symfony/branches/1.1/lib/storage/sfDatabaseSessionStorage.class.php on line 73

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /var/symfony/branches/1.1/lib/storage/sfMySQLSessionStorage.class.php:183) in /var/symfony/branches/1.1/lib/storage/sfDatabaseSessionStorage.class.php on line 73

Warning: Cannot modify header information - headers already sent by (output started at /var/symfony/branches/1.1/lib/storage/sfMySQLSessionStorage.class.php:183) in /var/symfony/branches/1.1/lib/exception/sfException.class.php on line 70

And the same exception as Joao...

stack trace

    * at ()
      in SF_SYMFONY_LIB_DIR/storage/sfMySQLSessionStorage.class.php line 126 ...
             123.       }
             124.
             125.       // can't create record
             126.       throw new sfDatabaseException(sprintf('% cannot create new record for id "%s" (%s).', get_class($this), $id, mysql_error()));
             127.     }
             128.   }
 129.
    * at sfMySQLSessionStorage->sessionRead('586cc0252e94d8b847065c34fbb9c7e0')
      in n/a line n/a ...
    * at session_start()
      in SF_SYMFONY_LIB_DIR/storage/sfDatabaseSessionStorage.class.php line 72 ...
              69.                              array($this, 'sessionGC'));
              70.
              71.     // start our session
              72.     session_start();
              73.   }
              74.
              75.   /**
    * at sfDatabaseSessionStorage->initialize(array('auto_shutdown' => '', null, object('sfPropelDatabase'), 'session_name' => 'worknt', 'db_table' => 'session', 'db_id_col' => 'session_id', 'db_data_col' => 'session_data', 'db_time_col' => 'session_time'))
      in SF_SYMFONY_LIB_DIR/storage/sfStorage.class.php line 33 ...
              30.    */
              31.   public function __construct($options = array())
              32.   {
              33.     $this->initialize($options);
              34.
              35.     if ($this->options['auto_shutdown'])
              36.     {
    * at sfStorage->__construct(array('auto_shutdown' => '', null, object('sfPropelDatabase'), 'session_name' => 'worknt', 'db_table' => 'session', 'db_id_col' => 'session_id', 'db_data_col' => 'session_data', 'db_time_col' => 'session_time'))
      in SF_ROOT_DIR/cache/myapp/dev/config/config_factories.yml.php line 109 ...
             106.   'db_id_col' => 'session_id',
             107.   'db_data_col' => 'session_data',
             108.   'db_time_col' => 'session_time',
             109. ))));
             110.   $class = sfConfig::get('sf_factory_user', 'myUser');
             111.   $this->factories['user'] = new $class($this->dispatcher, $this->factories['storage'], array_merge(array('auto_shutdown' => false, 'culture' => $this->factories['request']->getParameter('sf_culture')), sfConfig::get('sf_factory_user_parameters', array (
             112.   'timeout' => 1800,
    * at require('/var/www/boda/cache/myapp/dev/config/config_factories.yml.php')
      in SF_SYMFONY_LIB_DIR/util/sfContext.class.php line 154 ...
             151.     $this->factories['actionStack'] = new sfActionStack();
             152.
             153.     // include the factories configuration
             154.     require($this->configuration->getConfigCache()->checkConfig('config/factories.yml'));
             155.
             156.     $this->dispatcher->notify(new sfEvent($this, 'context.load_factories'));
             157.   }
    * at sfContext->loadFactories()
      in SF_SYMFONY_LIB_DIR/util/sfContext.class.php line 76 ...

I've changed factories.yml to use a MySQL table:

  storage:
    class: sfMySQLSessionStorage
    param:
      session_name: worknt
      db_table:    session                 # Name of the table storing the sessions
      database:    propel                  # Name of the database connection to use
      db_id_col:   session_id              # Name of the column storing the session id
      db_data_col: session_data            # Name of the column storing the session data
      db_time_col: session_time            # Name of the column storing the session timestamp

And created the session table on a test database:

CREATE TABLE IF NOT EXISTS `session` (
  `session_id` varchar(32) NOT NULL,
  `session_data` text NOT NULL,
  `session_time` int(11) NOT NULL
)

06/17/08 16:12:07 changed by Ajai.Khattri

Its not just remote databases - this error appears if you try to use a separate database connection on the same database server for session data. It looks like the session is initialized in the "session" database but then updates go to the main application database instead. Since the IDs in both database do not match, you get the "cannot create new record for id" error.

06/19/08 11:50:09 changed by FabianLange

  • status changed from new to closed.
  • resolution set to fixed.

(In [9662]) reverted r8506 & made mysql timestamp more robust. fixed #3647

06/20/08 15:49:52 changed by paulo_graca

  • status changed from closed to reopened.
  • resolution deleted.

The reverted Version it has a problem on line 183:

  /*!
   * Execute an SQL Query
   *
   * @param  string $query  The query to execute
   * @return mixed The result of the query
   */
  protected function db_query($query)
  {
    return @mysql_query($query, $this->db->getResource());
  }

The $this->db->getResource() method doesn't exists for the db object property. On the sfDatabaseSessionStorage abstract class:

 // get the database resource
    $this->db = $database->getResource();

So, probably the db_query and db_escape methods, should be instead:

return @mysql_query($query, $this->db);

(follow-up: ↓ 9 ) 06/20/08 15:53:40 changed by FabianLange

  • status changed from reopened to closed.
  • resolution set to fixed.

You are looking at an incorrect version of the file, or did not update completely: http://trac.symfony-project.com/browser/branches/1.1/lib/storage/sfMySQLSessionStorage.class.php?rev=9662

has the change you describe already

(in reply to: ↑ 8 ) 06/30/08 15:45:15 changed by Stasy

  • type changed from defect to enhancement.

There is an annoying thing with this fix, and I am wondering about the reason for why the MySQL Column type is changed back again:

Symfony 1.0 and 1.1 are using different MySQL column types for the "db_time_col" field. See file sfMySQLSessionStorage.class.php. In earlier versions of Symfony 1.0 the column type was "bigint", then it was changed to "datetime" since version 1.0.14. Symfony 1.1 was using "datetime" up to RC2, whereas Symfony 1.1 final now is using "bigint" again.

It's really annoying if you have to update your databases and database schema every few months... In my case, a customer upgraded a Symfony 1.0 installation and afterwards the application did not run anymore. Very bad as you can imagine...

I think the Symfony team should agree on ONE column type for the MySQLSessionStorage class!