[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