2

I have to migrate a php4 app that uses session_set_save_handler() to php5.

In php4 everything was fine, but in php5 the callback functions cannot access the global vars anymore, which were set on the page before session_set_save_handler() was called.

In the example below the global var $g1 cannot be accessed in the session_writer() (which is passed as a callback function)

Is there some explanation for this behavior or can you give a hint on migrating sessions with callbacks from php4 to 5?

This is the pseudo code:

function session_writer($id,$vars) {
  global $g1;
  echo "g1 not defined here: ".is_object($g1);
}

global $g1;
$g1 = SomeObject(); //which is the DB connection for the session writer

session_set_save_handler($o,$c,$r,"session_writer",$d,$g);
session_start();
hakre
  • 193,403
  • 52
  • 435
  • 836
user89021
  • 14,784
  • 16
  • 53
  • 65

2 Answers2

3

This is actually noted in the documentation:

As of PHP 5.0.5 the write and close handlers are called after object destruction and therefore cannot use objects or throw exceptions. The object destructors can however use sessions.

It is possible to call session_write_close() from the destructor to solve this chicken and egg problem.

Essentially, you'll have to call session_write_close() from the destructor of your SomeObject, or alternatively, do the following:

<?php register_shutdown_function("session_write_close"); ?>

Either of those solutions should force the writing and closing of the session before all objects are destroyed, allowing you to keep your original callback function.

Community
  • 1
  • 1
molf
  • 73,644
  • 13
  • 135
  • 118
  • Thank you, I am beginning to grasp what is happening here. SomeObject() is my Database. So I could refactor and copy the creation of the DB object to the session_writer itself, this would be easiest? – user89021 Jul 05 '09 at 22:10
  • No, they actually cannot use objects at all, unless you force the writing of the session *before* the objects are destroyed. As I said, you should call session_write_close() from some object destructor OR register it as shutdown function. – molf Jul 05 '09 at 22:15
0

Molf's answer identifies the problem. Here's some more info:

session_write_close() takes as input an identifier and the data associated with it. If you're going for minimal change, you'll probably need to know the data is what is returned by session_encode() (which is a string encoding the contents of the $_SESSION array). The identifier is what is returned by session_id().

mgkrebbs
  • 856
  • 15
  • 22