Attached is a patch (against HEAD, includes tests) which allows users to
extend any session handler in an object oriented fashion.

By extending the new internal class SessionHandler, users can wrap or
override methods of whatever session handler is in use, or implement a
complete custom handler.

Usage notes:
- Calling session_set_save_handler(class) after session_set_save_handler(a,
b, c, d, e, f) wouldn't transparently extend the first call since they share
the same storage. However this can be achieved by calling the former
functions manually from the class.
- Likewise multiple session_set_save_handler(class) calls simply replace
each other; just extend the new class from the old one instead of
SessionHandler to chain them.

Implementation notes:
- mod_user.c was faking PS(mod_data) so it would get called at the right
times. Now that we need to preserve the data for whatever handler we're
wrapping, session.c checks the new global PS(mod_active) instead. No more
tests are failing but I think it's possible this could break existing user
session modules so please look at this carefully. We could just do
PS(mod_data) || PS(var_controlled_by_mod_user) to be on the safe side, at
the expense of a very slight overhead for other session modules.

I've experimented with a few different ways of approaching this already.
Although I like this one (reusing the mod_user callbacks) because the change
is pretty minimal, it might be better to just store a pointer to the class
entry or the function entries. Or something entirely different..

I'd be grateful for any comments.

Arpad
Index: ext/session/config.w32
===================================================================
--- ext/session/config.w32	(revision 291124)
+++ ext/session/config.w32	(working copy)
@@ -4,7 +4,7 @@
 ARG_ENABLE("session", "session support", "yes");
 
 if (PHP_SESSION == "yes") {
-	EXTENSION("session", "session.c mod_files.c mod_mm.c mod_user.c", false /* never shared */);
+	EXTENSION("session", "mod_user_class.c session.c mod_files.c mod_mm.c mod_user.c", false /* never shared */);
 	AC_DEFINE("HAVE_PHP_SESSION", 1, "Session support");
 }
 
Index: ext/session/php_session.h
===================================================================
--- ext/session/php_session.h	(revision 291124)
+++ ext/session/php_session.h	(working copy)
@@ -128,6 +128,7 @@
 	zend_bool  cookie_secure;
 	zend_bool  cookie_httponly;
 	ps_module *mod;
+	ps_module *old_mod;
 	void *mod_data;
 	php_session_status session_status;
 	long gc_probability;
@@ -146,6 +147,7 @@
 			zval *ps_gc;
 		} name;
 	} mod_user_names;
+	int mod_active;
 	const struct ps_serializer_struct *serializer;
 	zval *http_session_vars;
 	zend_bool auto_start;
@@ -285,4 +287,14 @@
 void php_session_auto_start(void *data);
 void php_session_shutdown(void *data);
 
+#define PS_CLASS_NAME "SessionHandler"
+extern zend_class_entry *php_session_class_entry;
+
+extern PHP_METHOD(SessionHandler, open);
+extern PHP_METHOD(SessionHandler, close);
+extern PHP_METHOD(SessionHandler, read);
+extern PHP_METHOD(SessionHandler, write);
+extern PHP_METHOD(SessionHandler, destroy);
+extern PHP_METHOD(SessionHandler, gc);
+
 #endif
Index: ext/session/mod_user_class.c
===================================================================
--- ext/session/mod_user_class.c	(revision 0)
+++ ext/session/mod_user_class.c	(revision 0)
@@ -0,0 +1,123 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 6                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2009 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | lice...@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Arpad Ray <ar...@php.net>
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+#include "php_session.h"
+
+#define PS_SANITY_CHECK						\
+	if (PS(old_mod) == NULL) {				\
+		RETURN_FALSE;						\
+	}							
+
+
+/* {{{ proto bool SessionHandler::open(string save_path, string session_name)
+   Wraps the old open handler */
+PHP_METHOD(SessionHandler, open)
+{
+	PS_SANITY_CHECK;
+
+	RETVAL_LONG(PS(old_mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name) TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto bool SessionHandler::close()
+   Wraps the old close handler */
+PHP_METHOD(SessionHandler, close)
+{
+	PS_SANITY_CHECK;
+
+	RETVAL_LONG(PS(old_mod)->s_close(&PS(mod_data) TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto bool SessionHandler::read(save_path, session_name)
+   Wraps the old read handler */
+PHP_METHOD(SessionHandler, read)
+{
+	char *key, *val;
+	int key_len, val_len;
+
+	PS_SANITY_CHECK;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len, UG(utf8_conv)) == FAILURE) {
+		return;
+	}
+
+	if (PS(old_mod)->s_read(&PS(mod_data), key, &val, &val_len TSRMLS_CC) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	RETVAL_STRINGL(val, val_len, 1);
+	efree(val);
+	return;
+}
+/* }}} */
+
+/* {{{ proto bool SessionHandler::write(save_path, session_name)
+   Wraps the old write handler */
+PHP_METHOD(SessionHandler, write)
+{
+	char *key, *val;
+	int key_len, val_len;
+
+	PS_SANITY_CHECK;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &key, &key_len, &val, &val_len, UG(utf8_conv)) == FAILURE) {
+		return;
+	}
+
+	RETVAL_LONG(PS(old_mod)->s_write(&PS(mod_data), key, val, val_len TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto bool SessionHandler::destroy()
+   Wraps the old destroy handler */
+PHP_METHOD(SessionHandler, destroy)
+{
+	char *key;
+	int key_len;
+
+	PS_SANITY_CHECK;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len, UG(utf8_conv)) == FAILURE) {
+		return;
+	}
+	
+	RETVAL_LONG(PS(old_mod)->s_destroy(&PS(mod_data), key TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto bool SessionHandler::gc(int maxlifetime)
+   Wraps the old gc handler */
+PHP_METHOD(SessionHandler, gc)
+{
+	long maxlifetime;
+	int nrdels;
+
+	PS_SANITY_CHECK;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &maxlifetime, UG(utf8_conv)) == FAILURE) {
+		return;
+	}
+	
+	RETVAL_LONG(PS(old_mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels TSRMLS_CC));
+}
+/* }}} */
+
Index: ext/session/config.m4
===================================================================
--- ext/session/config.m4	(revision 291124)
+++ ext/session/config.m4	(working copy)
@@ -11,7 +11,7 @@
 if test "$PHP_SESSION" != "no"; then
   PHP_PWRITE_TEST
   PHP_PREAD_TEST
-  PHP_NEW_EXTENSION(session, session.c mod_files.c mod_mm.c mod_user.c, $ext_shared)
+  PHP_NEW_EXTENSION(session, mod_user_class.c session.c mod_files.c mod_mm.c mod_user.c, $ext_shared)
   PHP_ADD_EXTENSION_DEP(session, hash, true)
   PHP_SUBST(SESSION_SHARED_LIBADD)
   PHP_INSTALL_HEADERS(ext/session, [php_session.h mod_files.h mod_user.h])
Index: ext/session/package.xml
===================================================================
--- ext/session/package.xml	(revision 291124)
+++ ext/session/package.xml	(working copy)
@@ -40,6 +40,7 @@
    <file role="src" name="mod_mm.c"/>
    <file role="src" name="mod_mm.h"/>
    <file role="src" name="mod_user.c"/>
+   <file role="src" name="mod_user_class.c"/>
    <file role="src" name="mod_user.h"/>
    <file role="src" name="php_session.h"/>
    <file role="src" name="session.c"/>
Index: ext/session/mod_user.c
===================================================================
--- ext/session/mod_user.c	(revision 291124)
+++ ext/session/mod_user.c	(working copy)
@@ -62,15 +62,10 @@
 	return retval;
 }
 
-#define STDVARS1							\
+#define STDVARS								\
 	zval *retval;							\
 	int ret = FAILURE
 
-#define STDVARS								\
-	STDVARS1;								\
-	char *mdata = PS_GET_MOD_DATA();		\
-	if (!mdata) { return FAILURE; }
-
 #define PSF(a) PS(mod_user_names).name.ps_##a
 
 #define FINISH								\
@@ -84,33 +79,24 @@
 PS_OPEN_FUNC(user)
 {
 	zval *args[2];
-	static char dummy = 0;
-	STDVARS1;
+	STDVARS;
 
 	SESS_ZVAL_STRING((char*)save_path, args[0]);
 	SESS_ZVAL_STRING((char*)session_name, args[1]);
 
 	retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
-	if (retval) {
-		/* This is necessary to fool the session module. Yes, it's safe to
-		 * use a static. Neither mod_user nor the session module itself will
-		 * ever touch this pointer. It could be set to 0xDEADBEEF for all the
-		 * difference it makes, but for the sake of paranoia it's set to some
-		 * valid value. */
-		PS_SET_MOD_DATA(&dummy);
-	}
+	PS(mod_active) = 1;
 
 	FINISH;
 }
 
 PS_CLOSE_FUNC(user)
 {
-	STDVARS1;
+	STDVARS;
 
 	retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC);
+	PS(mod_active) = 0;
 
-	PS_SET_MOD_DATA(NULL);
-
 	FINISH;
 }
 
Index: ext/session/tests/session_set_save_handler_class.phpt
===================================================================
--- ext/session/tests/session_set_save_handler_class.phpt	(revision 0)
+++ ext/session/tests/session_set_save_handler_class.phpt	(revision 0)
@@ -0,0 +1,197 @@
+--TEST--
+Test session_set_save_handler() function : class handler
+--INI--
+session.save_path=
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/* 
+ * Prototype : bool session_set_save_handler(string $class)
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c 
+ */
+
+echo "*** Testing session_set_save_handler() : class handler ***\n";
+
+echo "*** Testing session_set_save_handler() : basic class wrapping existing handler ***\n";
+
+class MySession extends SessionHandler {
+	public static $i = 0;
+	public static function open($path, $name) {
+		++self::$i;
+		echo 'Open ', session_id(), "\n";
+		return parent::open($path, $name);
+	}
+	public static function read($key) {
+		++self::$i;
+		echo 'Read ', session_id(), "\n";
+		return parent::read($key);
+	}
+}
+
+$path = dirname(__FILE__);
+session_save_path($path);
+
+$oldHandler = ini_get('session.save_handler');
+session_set_save_handler('MySession');
+session_start();
+
+var_dump(session_id(), $oldHandler, ini_get('session.save_handler'), MySession::$i, $_SESSION);
+
+$_SESSION['foo'] = "\u263A";
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+echo "*** Testing session_set_save_handler() : full handler implementation ***\n";
+
+class MySession2 extends SessionHandler {
+	public static $path;
+
+	public static function open($path, $name) {
+		if (!$path) {
+			$path = '/tmp';
+		}
+		self::$path = $path . '/u_sess_' . $name;
+		return true;
+	}
+
+	public static function close() {
+		return true;
+	}
+
+	public static function read($id) {
+		return @file_get_contents(self::$path . $id);
+	}
+
+	public static function write($id, $data) {
+		return file_put_contents(self::$path . $id, $data);
+	}
+
+	public static function destroy($id) {
+		@unlink(self::$path . $id);
+	}
+
+	public static function gc($maxlifetime) {
+		foreach (glob(self::$path . '*') as $filename) {
+			if (filemtime($filename) + $maxlifetime < time()) {
+				@unlink($filename);
+			}
+		}
+		return true;
+	}
+}
+
+session_set_save_handler('MySession2');
+session_start();
+
+$_SESSION['foo'] = "\u263A";
+
+var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+echo "*** Testing session_set_save_handler() : inheritance ***\n";
+
+class MySession3 extends SessionHandler {
+	public static $i = 0;
+	public static function open($path, $name) {
+		++MySession3::$i;
+		return parent::open($path, $name);
+	}
+	public static function read($key) {
+		++MySession3::$i;
+		return parent::read($key);
+	}
+}
+
+class MySession4 extends MySession3 {
+	public static function write($id, $data) {
+		MySession3::$i = "hai";
+		return parent::write($id, $data);
+	}
+}
+
+session_set_save_handler('MySession3');
+session_start();
+
+$_SESSION['foo'] = "\u263A";
+
+session_write_close();
+session_unset();
+
+session_start();
+
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+session_set_save_handler('MySession4');
+
+session_start();
+
+session_write_close();
+session_unset();
+
+var_dump(session_id(), $_SESSION, MySession3::$i);
+
+ob_end_flush();
+?>
+--EXPECTF--
+*** Testing session_set_save_handler() : class handler ***
+*** Testing session_set_save_handler() : basic class wrapping existing handler ***
+Open 
+Read %x
+string(32) "%x"
+unicode(5) "files"
+unicode(4) "user"
+int(2)
+array(0) {
+}
+Open %x
+Read %x
+array(1) {
+  [u"foo"]=>
+  unicode(1) "☺"
+}
+*** Testing session_set_save_handler() : full handler implementation ***
+string(32) "%x"
+unicode(4) "user"
+array(1) {
+  [u"foo"]=>
+  unicode(1) "☺"
+}
+array(1) {
+  [u"foo"]=>
+  unicode(1) "☺"
+}
+*** Testing session_set_save_handler() : inheritance ***
+array(1) {
+  [u"foo"]=>
+  unicode(1) "☺"
+}
+string(32) "%x"
+array(1) {
+  [u"foo"]=>
+  unicode(1) "☺"
+}
+unicode(3) "hai"
Index: ext/session/session.c
===================================================================
--- ext/session/session.c	(revision 291124)
+++ ext/session/session.c	(working copy)
@@ -94,9 +94,10 @@
 		PS(http_session_vars) = NULL;
 	}
 	/* Do NOT destroy PS(mod_user_names) here! */
-	if (PS(mod_data)) {
+	if (PS(mod_active)) {
 		zend_try {
 			PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
+			PS(mod_active) = 0;
 		} zend_end_try();
 	}
 	if (PS(id)) {
@@ -411,6 +412,8 @@
 		return;
 	}
 
+	PS(mod_active) = 1;
+
 	/* Open session handler first */
 	if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name) TSRMLS_CC) == FAILURE) {
 		php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to initialize storage module: %s (path: %s)", PS(mod)->s_name, PS(save_path));
@@ -451,7 +454,7 @@
 
 	IF_SESSION_VARS() {
 
-		if (PS(mod_data)) {
+		if (PS(mod_active)) {
 			char *val;
 			int vallen;
 
@@ -473,8 +476,9 @@
 		}
 	}
 
-	if (PS(mod_data)) {
+	if (PS(mod_active)) {
 		PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
+		PS(mod_active) = 0;
 	}
 }
 /* }}} */
@@ -505,6 +509,7 @@
 		}
 		return FAILURE;
 	}
+	PS(old_mod) = PS(mod);
 	PS(mod) = tmp;
 
 	return SUCCESS;
@@ -1381,7 +1386,7 @@
 
 	php_session_cache_limiter(TSRMLS_C);
 
-	if (PS(mod_data) && PS(gc_probability) > 0) {
+	if (PS(mod_active) && PS(gc_probability) > 0) {
 		int nrdels = -1;
 
 		nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg(TSRMLS_C));
@@ -1516,8 +1521,9 @@
 			zval_dtor(return_value);
 			RETURN_FALSE;
 		}
-		if (PS(mod_data)) {
+		if (PS(mod_active)) {
 			PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
+			PS(mod_active) = 0;
 		}
 		PS(mod_data) = NULL;
 
@@ -1526,7 +1532,20 @@
 }
 /* }}} */
 
-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) U
+#define PS_METHOD_CALLBACK(x)											\
+	callback = PS(mod_user_names).name.ps_##x;							\
+	if (callback != NULL) {												\
+		zval_ptr_dtor(&callback);										\
+		callback = NULL;												\
+	}																	\
+																		\
+	MAKE_STD_ZVAL(callback);											\
+	array_init(callback);												\
+	add_next_index_zstrl(callback, IS_UNICODE, class, class_len, 1);	\
+	add_next_index_string(callback, #x, 1);								\
+	PS(mod_user_names).name.ps_##x = callback;
+
+/* {{{ proto void session_set_save_handler(string open [, string close, string read, string write, string destroy, string gc]) U
    Sets user-level functions */
 static PHP_FUNCTION(session_set_save_handler)
 {
@@ -1538,10 +1557,51 @@
 		RETURN_FALSE;
 	}
 
-	if (argc != 6) {
+	if (argc != 1 && argc != 6) {
 		WRONG_PARAM_COUNT;
 	}
 
+	if (argc == 1) {
+		zstr class;
+		uint class_len;
+		zend_class_entry **pce, *ce = NULL;
+		zval *callback;
+
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "u", &class, &class_len) == FAILURE) {
+			return;
+		}
+	
+		if (zend_u_lookup_class(IS_UNICODE, class, class_len, &pce TSRMLS_CC) == FAILURE) {
+			php_error_docref(NULL TSRMLS_CC, E_ERROR, "The provided class (%s) does not exist", class);
+			RETURN_FALSE;
+		}
+
+		ce = *pce;
+		while (ce->parent) {
+			ce = ce->parent;
+		}
+
+		if (ce != php_session_class_entry) {
+			php_error_docref(NULL TSRMLS_CC, E_ERROR, "The session handler class must descend from %s", PS_CLASS_NAME);
+			RETURN_FALSE;
+		}
+		
+		PS_METHOD_CALLBACK(open);
+		PS_METHOD_CALLBACK(close);
+		PS_METHOD_CALLBACK(read);
+		PS_METHOD_CALLBACK(write);
+		PS_METHOD_CALLBACK(destroy);
+		PS_METHOD_CALLBACK(gc);
+
+		if (PS(mod) && PS(session_status) == php_session_none && PS(mod) != &ps_mod_user) {
+			PS(old_mod) = PS(mod);
+			zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
+		}
+
+		PS(mod_active) = 1;
+		RETURN_TRUE;
+	}
+
 	if (zend_parse_parameters(argc TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
 		return;
 	}
@@ -1555,7 +1615,8 @@
 		}
 		zval_dtor(&name);
 	}
-
+	
+	PS(mod_active) = 1;
 	zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
 
 	for (i = 0; i < 6; i++) {
@@ -1885,6 +1946,31 @@
 	ZEND_ARG_INFO(0, secure)
 	ZEND_ARG_INFO(0, httponly)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_open, 0)
+	ZEND_ARG_INFO(0, save_path)
+	ZEND_ARG_INFO(0, session_name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_close, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_read, 0)
+	ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_write, 0)
+	ZEND_ARG_INFO(0, key)
+	ZEND_ARG_INFO(0, val)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_destroy, 0)
+	ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_gc, 0)
+	ZEND_ARG_INFO(0, maxlifetime)
+ZEND_END_ARG_INFO()
 /* }}} */
 
 /* {{{ session_functions[]
@@ -1911,6 +1997,22 @@
 };
 /* }}} */
 
+/* session class */
+zend_class_entry *php_session_class_entry;
+
+/* {{{ session class functions[]
+ */
+static const zend_function_entry php_session_class_functions[] = {
+	PHP_ME(SessionHandler, open, arginfo_session_class_open, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+	PHP_ME(SessionHandler, close, arginfo_session_class_close, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+	PHP_ME(SessionHandler, read, arginfo_session_class_read, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+	PHP_ME(SessionHandler, write, arginfo_session_class_write, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+	PHP_ME(SessionHandler, destroy, arginfo_session_class_destroy, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+	PHP_ME(SessionHandler, gc, arginfo_session_class_gc, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+	{ NULL, NULL, NULL }
+};
+/* }}} */
+
 /* ********************************
    * Module Setup and Destruction *
    ******************************** */
@@ -1986,15 +2088,19 @@
 	ps_globals->serializer = NULL;
 	ps_globals->mod_data = NULL;
 	ps_globals->session_status = php_session_none;
+	ps_globals->mod_active = 0;
 	for (i = 0; i < 6; i++) {
 		ps_globals->mod_user_names.names[i] = NULL;
 	}
+
 	ps_globals->http_session_vars = NULL;
 }
 /* }}} */
 
 static PHP_MINIT_FUNCTION(session) /* {{{ */
 {
+	zend_class_entry ce;
+
 	zend_register_auto_global("_SESSION", sizeof("_SESSION")-1, NULL TSRMLS_CC);
 
 	PS(module_number) = module_number; /* if we really need this var we need to init it in zts mode as well! */
@@ -2007,6 +2113,10 @@
 #endif
 	php_session_rfc1867_orig_callback = php_rfc1867_callback;
 	php_rfc1867_callback = php_session_rfc1867_callback;
+
+	INIT_CLASS_ENTRY(ce, PS_CLASS_NAME, php_session_class_functions);
+	php_session_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+
 	return SUCCESS;
 }
 /* }}} */
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to