[development] Add data to Drupal session

Larry Garfield larry at garfieldtech.com
Wed Dec 9 05:57:25 UTC 2009


That's not entirely true.

In PHP, you can store an object of a class into the session (or any other 
serialized data structure) IFF the class is defined when the data is 
unserialized OR it can be autoloaded at that time.

Drupal opens its session before any modules have loaded, so you cannot have 
the classes defined.  Drupal 6 has no autoload mechanism natively.  There is an 
Autoload module (http://drupal.org/project/autoload) that enables autoload 
functionality but it doesn't take effect until hook_init(), which is after the 
session has started.

However, you can certainly include the necessary files yourself before the 
session opens.  The place to do that is in settings.php.  That's not a great 
distributable solution, but for your specific site it can work fine.  I'm doing 
that on a site I'm working on right now.  It's best if you move the class to 
its own file and then include_once() that file both from the corresponding 
.module file and from settings.php, so that you know it will be there when you 
need it.  Poof, classes work in the session.

Drupal 7 has a built-in class autoloader that initializes before the session 
does, so that won't be a problem going forward.

It's true that resources like DB connections or file handles don't survive 
serialization.  That's why PHP offers the __sleep() and __wakeup() magic 
methods that you can use to control what gets serialized or deserialized if 
necessary.  You can find more on them on http://www.php.net/

On Tuesday 08 December 2009 11:52:25 am Sascha Grossenbacher wrote:
> Short answer: you can't.
>
> Even if you are able to serialize your class, I'm sure the class
> contains resources
> (http://www.php.net/manual/en/language.types.resource.php) and these
> cannot be serialized nor stored in $_SESSION. Some resources can be
> persistent but I think that's only possible with PHP extensions aka C
> code.
>
> I'm sure there are other possible solutions, including a running
> process/service on the server to which either your module can talk.
>
> On Tue, Dec 8, 2009 at 5:42 PM, Salvatore De Paolis <iwkse at gmx.com> wrote:
> > Hi,
> >
> > I'm new to this mailing list, I hope is the right place to ask for such
> > questions.
> > I'm writing a module for drupal which implements a jabber client and
> > hooks in the appbar module.
> > The issue i'm having now is regarding the data used for jabber
> > communication. I'm using a jabber class and I need to store this object
> > somewhere so that the _init code is just executed one time.
> > I thought about sessions and I found a couple of ways, both don't works
> > properly for me.
> >
> > First is using the global $user:
> >
> > function jwclient_jabberclass_init() {
> >   global $user;
> >   if (!isset($user->jabclient) && $user->uid) {
> >       require_once('jabber.php');
> >       ...
> >       $jab = New Jabber($debug);
> >       $jabclient = New JabberClient($jab);
> >       $jabclient->jabber_client_set_user($user);
> >       ...
> >       user_save($user, array('jabclient' => $jabclient));
> >   }
> > }
> > function jwclient_init() {
> >  jwclient_jabberclass_init();
> >  ...
> > }
> > function theme_jwclient_chat () {
> >  global $user;
> >  return $user->jabclient->status;
> > }
> >
> > This solution gives me an errors of __PHP_Incomplete_Class Object.
> > Googling in understood that a proper way to save classes in session is to
> > fistly define the class and than call session_start. I don't see ways to
> > achieve this since the class I'm using is defined in a module and the
> > drupal session is already initiated.
> > A workaround i found on drupal.org is by using serialize/unserialize but
> > it doesn't work around for this case.
> > I changed the code in this way:
> >
> > function jwclient_jabberclass_init() {
> >   global $user;
> >   if (!isset($user->jabclient) && $user->uid) {
> >       require_once('jabber.php');
> >       ...
> >       $jab = New Jabber($debug);
> >       $jabclient = New JabberClient($jab);
> >       $jabclient->jabber_client_set_user($user);
> >       ...
> >       $jabclient = serialize($jabclient);
> >       user_save($user, array('jabclient' => $jabclient));
> >   }
> > }
> > function jwclient_init() {
> >  jwclient_jabberclass_init();
> >  ...
> > }
> > function theme_jwclient_chat () {
> >  global $user;
> >  $jabclient = $user->jabclient;
> >  $jabclient = unserialize($jabclient);
> >  return $user->jabclient->status;
> > }
> > The result is: warning: unserialize() expects parameter 1 to be string,
> > object given
> >
> > After this, i give away $user and tried with $_SESSION
> >
> > function jwclient_jabberclass_init() {
> >   global $user;
> >   if (is_null($_SESSION['jabclient']) && $user->uid) {
> >       require_once('jabber.php');
> >       ...
> >       $jab = New Jabber($debug);
> >       $jabclient = New JabberClient($jab);
> >       $jabclient->jabber_client_set_user($user);
> >       ...
> >       $_SESSION['jabclient'] = serialize($jabclient);
> >   }
> > }
> > function jwclient_init() {
> >  jwclient_jabberclass_init();
> >  ...
> > }
> > function theme_jwclient_chat () {
> >  $jabclient = unserialize($_SESSION['jabclient']);
> >  return $jabclient->status;
> > }
> > This attempt works on the first call. On the second call I get again the
> > error about __PHP_Incomplete_Class Object.
> >
> > I'm out of clue now.
> > Anyone know how to manage the case of storing objects in session with
> > drupal?
> >
> > Thanks,
> > Salvatore

-- 
Larry Garfield
larry at garfieldtech.com


More information about the development mailing list