arpad                                    Wed, 04 Jan 2012 01:16:45 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=321738

Log:
add SessionHandlerInterface for session_set_save_handler() - #60551

Bug: https://bugs.php.net/60551 (Duplicate) session_set_save_handler should 
support a core's session handler interface
      
Changed paths:
    U   php/php-src/branches/PHP_5_4/ext/session/php_session.h
    U   php/php-src/branches/PHP_5_4/ext/session/session.c
    A   
php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_001.phpt
    A   
php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_002.phpt
    U   php/php-src/trunk/ext/session/php_session.h
    U   php/php-src/trunk/ext/session/session.c
    A   
php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_001.phpt
    A   
php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_002.phpt

Modified: php/php-src/branches/PHP_5_4/ext/session/php_session.h
===================================================================
--- php/php-src/branches/PHP_5_4/ext/session/php_session.h	2012-01-04 00:32:05 UTC (rev 321737)
+++ php/php-src/branches/PHP_5_4/ext/session/php_session.h	2012-01-04 01:16:45 UTC (rev 321738)
@@ -274,6 +274,9 @@
 #define PS_CLASS_NAME "SessionHandler"
 extern zend_class_entry *php_session_class_entry;

+#define PS_IFACE_NAME "SessionHandlerInterface"
+extern zend_class_entry *php_session_iface_entry;
+
 extern PHP_METHOD(SessionHandler, open);
 extern PHP_METHOD(SessionHandler, close);
 extern PHP_METHOD(SessionHandler, read);

Modified: php/php-src/branches/PHP_5_4/ext/session/session.c
===================================================================
--- php/php-src/branches/PHP_5_4/ext/session/session.c	2012-01-04 00:32:05 UTC (rev 321737)
+++ php/php-src/branches/PHP_5_4/ext/session/session.c	2012-01-04 01:16:45 UTC (rev 321738)
@@ -67,6 +67,9 @@
 /* SessionHandler class */
 zend_class_entry *php_session_class_entry;

+/* SessionHandlerInterface */
+zend_class_entry *php_session_iface_entry;
+
 /* ***********
    * Helpers *
    *********** */
@@ -1598,8 +1601,8 @@
 		php_shutdown_function_entry shutdown_function_entry;
 		zend_bool register_shutdown = 1;

-		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, php_session_class_entry, &register_shutdown) == FAILURE) {
-			return;
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, php_session_iface_entry, &register_shutdown) == FAILURE) {
+			RETURN_FALSE;
 		}

 		/* Find implemented methods */
@@ -1673,7 +1676,6 @@
 		efree(name);
 	}

-
 	if (PS(mod) && PS(mod) != &ps_mod_user) {
 		zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
 	}
@@ -2065,7 +2067,20 @@
 };
 /* }}} */

-/* {{{ session class functions[]
+/* {{{ SessionHandlerInterface functions[]
+*/
+static const zend_function_entry php_session_iface_functions[] = {
+	PHP_ABSTRACT_ME(SessionHandlerInterface, open, arginfo_session_class_open)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, close, arginfo_session_class_close)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, read, arginfo_session_class_read)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, write, arginfo_session_class_write)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, destroy, arginfo_session_class_destroy)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, gc, arginfo_session_class_gc)
+	{ NULL, NULL, NULL }
+};
+/* }}} */
+
+/* {{{ SessionHandler functions[]
  */
 static const zend_function_entry php_session_class_functions[] = {
 	PHP_ME(SessionHandler, open, arginfo_session_class_open, ZEND_ACC_PUBLIC)
@@ -2180,9 +2195,15 @@
 	php_session_rfc1867_orig_callback = php_rfc1867_callback;
 	php_rfc1867_callback = php_session_rfc1867_callback;

+	/* Register interface */
+	INIT_CLASS_ENTRY(ce, PS_IFACE_NAME, php_session_iface_functions);
+	php_session_iface_entry = zend_register_internal_class(&ce TSRMLS_CC);
+	php_session_iface_entry->ce_flags |= ZEND_ACC_INTERFACE;
+
 	/* Register base class */
 	INIT_CLASS_ENTRY(ce, PS_CLASS_NAME, php_session_class_functions);
 	php_session_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+	zend_class_implements(php_session_class_entry TSRMLS_CC, 1, php_session_iface_entry);

 	REGISTER_LONG_CONSTANT("PHP_SESSION_DISABLED", php_session_disabled, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("PHP_SESSION_NONE", php_session_none, CONST_CS | CONST_PERSISTENT);

Added: php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_001.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_001.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_001.phpt	2012-01-04 01:16:45 UTC (rev 321738)
@@ -0,0 +1,113 @@
+--TEST--
+Test session_set_save_handler() function: interface
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: interface ***\n";
+
+class MySession2 implements SessionHandlerInterface {
+	public $path;
+
+	public function open($path, $name) {
+		if (!$path) {
+			$path = '/tmp';
+		}
+		$this->path = $path . '/u_sess_' . $name;
+		return true;
+	}
+
+	public function close() {
+		return true;
+	}
+
+	public function read($id) {
+		return @file_get_contents($this->path . $id);
+	}
+
+	public function write($id, $data) {
+		return file_put_contents($this->path . $id, $data);
+	}
+
+	public function destroy($id) {
+		@unlink($this->path . $id);
+	}
+
+	public function gc($maxlifetime) {
+		foreach (glob($this->path . '*') as $filename) {
+			if (filemtime($filename) + $maxlifetime < time()) {
+				@unlink($filename);
+			}
+		}
+		return true;
+	}
+}
+
+$handler = new MySession2;
+session_set_save_handler(array($handler, 'open'), array($handler, 'close'),
+	array($handler, 'read'), array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc'));
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+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();
+
+session_set_save_handler($handler);
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+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();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: interface ***
+string(%d) "%s"
+string(4) "user"
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}
+string(%d) "%s"
+string(4) "user"
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}

Added: php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_002.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_002.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_4/ext/session/tests/session_set_save_handler_iface_002.phpt	2012-01-04 01:16:45 UTC (rev 321738)
@@ -0,0 +1,90 @@
+--TEST--
+Test session_set_save_handler() function: interface wrong
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: interface wrong ***\n";
+
+interface MySessionHandlerInterface {
+	public function open($path, $name);
+	public function close();
+	public function read($id);
+	public function write($id, $data);
+	public function destroy($id);
+	public function gc($maxlifetime);
+}
+
+class MySession2 implements MySessionHandlerInterface {
+	public $path;
+
+	public function open($path, $name) {
+		if (!$path) {
+			$path = '/tmp';
+		}
+		$this->path = $path . '/u_sess_' . $name;
+		return true;
+	}
+
+	public function close() {
+		return true;
+	}
+
+	public function read($id) {
+		return @file_get_contents($this->path . $id);
+	}
+
+	public function write($id, $data) {
+		echo "Unsupported session handler in use\n";
+	}
+
+	public function destroy($id) {
+		@unlink($this->path . $id);
+	}
+
+	public function gc($maxlifetime) {
+		foreach (glob($this->path . '*') as $filename) {
+			if (filemtime($filename) + $maxlifetime < time()) {
+				@unlink($filename);
+			}
+		}
+		return true;
+	}
+}
+
+function good_write($id, $data) {
+	global $handler;
+	echo "good handler writing\n";
+	return file_put_contents($handler->path . $id, $data);
+}
+
+$handler = new MySession2;
+
+$ret = session_set_save_handler(array($handler, 'open'), array($handler, 'close'),
+	array($handler, 'read'), 'good_write', array($handler, 'destroy'), array($handler, 'gc'));
+
+var_dump($ret);
+$ret = session_set_save_handler($handler);
+var_dump($ret);
+
+session_start();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: interface wrong ***
+bool(true)
+
+Warning: session_set_save_handler() expects parameter 1 to be SessionHandlerInterface, object given in %s
+bool(false)
+good handler writing

Modified: php/php-src/trunk/ext/session/php_session.h
===================================================================
--- php/php-src/trunk/ext/session/php_session.h	2012-01-04 00:32:05 UTC (rev 321737)
+++ php/php-src/trunk/ext/session/php_session.h	2012-01-04 01:16:45 UTC (rev 321738)
@@ -274,6 +274,9 @@
 #define PS_CLASS_NAME "SessionHandler"
 extern zend_class_entry *php_session_class_entry;

+#define PS_IFACE_NAME "SessionHandlerInterface"
+extern zend_class_entry *php_session_iface_entry;
+
 extern PHP_METHOD(SessionHandler, open);
 extern PHP_METHOD(SessionHandler, close);
 extern PHP_METHOD(SessionHandler, read);

Modified: php/php-src/trunk/ext/session/session.c
===================================================================
--- php/php-src/trunk/ext/session/session.c	2012-01-04 00:32:05 UTC (rev 321737)
+++ php/php-src/trunk/ext/session/session.c	2012-01-04 01:16:45 UTC (rev 321738)
@@ -67,6 +67,9 @@
 /* SessionHandler class */
 zend_class_entry *php_session_class_entry;

+/* SessionHandlerInterface */
+zend_class_entry *php_session_iface_entry;
+
 /* ***********
    * Helpers *
    *********** */
@@ -1598,8 +1601,8 @@
 		php_shutdown_function_entry shutdown_function_entry;
 		zend_bool register_shutdown = 1;

-		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, php_session_class_entry, &register_shutdown) == FAILURE) {
-			return;
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, php_session_iface_entry, &register_shutdown) == FAILURE) {
+			RETURN_FALSE;
 		}

 		/* Find implemented methods */
@@ -2064,7 +2067,20 @@
 };
 /* }}} */

-/* {{{ session class functions[]
+/* {{{ SessionHandlerInterface functions[]
+*/
+static const zend_function_entry php_session_iface_functions[] = {
+	PHP_ABSTRACT_ME(SessionHandlerInterface, open, arginfo_session_class_open)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, close, arginfo_session_class_close)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, read, arginfo_session_class_read)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, write, arginfo_session_class_write)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, destroy, arginfo_session_class_destroy)
+	PHP_ABSTRACT_ME(SessionHandlerInterface, gc, arginfo_session_class_gc)
+	{ NULL, NULL, NULL }
+};
+/* }}} */
+
+/* {{{ SessionHandler functions[]
  */
 static const zend_function_entry php_session_class_functions[] = {
 	PHP_ME(SessionHandler, open, arginfo_session_class_open, ZEND_ACC_PUBLIC)
@@ -2179,9 +2195,15 @@
 	php_session_rfc1867_orig_callback = php_rfc1867_callback;
 	php_rfc1867_callback = php_session_rfc1867_callback;

+	/* Register interface */
+	INIT_CLASS_ENTRY(ce, PS_IFACE_NAME, php_session_iface_functions);
+	php_session_iface_entry = zend_register_internal_class(&ce TSRMLS_CC);
+	php_session_iface_entry->ce_flags |= ZEND_ACC_INTERFACE;
+
 	/* Register base class */
 	INIT_CLASS_ENTRY(ce, PS_CLASS_NAME, php_session_class_functions);
 	php_session_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+	zend_class_implements(php_session_class_entry TSRMLS_CC, 1, php_session_iface_entry);

 	REGISTER_LONG_CONSTANT("PHP_SESSION_DISABLED", php_session_disabled, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("PHP_SESSION_NONE", php_session_none, CONST_CS | CONST_PERSISTENT);

Added: php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_001.phpt
===================================================================
--- php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_001.phpt	                        (rev 0)
+++ php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_001.phpt	2012-01-04 01:16:45 UTC (rev 321738)
@@ -0,0 +1,113 @@
+--TEST--
+Test session_set_save_handler() function: interface
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: interface ***\n";
+
+class MySession2 implements SessionHandlerInterface {
+	public $path;
+
+	public function open($path, $name) {
+		if (!$path) {
+			$path = '/tmp';
+		}
+		$this->path = $path . '/u_sess_' . $name;
+		return true;
+	}
+
+	public function close() {
+		return true;
+	}
+
+	public function read($id) {
+		return @file_get_contents($this->path . $id);
+	}
+
+	public function write($id, $data) {
+		return file_put_contents($this->path . $id, $data);
+	}
+
+	public function destroy($id) {
+		@unlink($this->path . $id);
+	}
+
+	public function gc($maxlifetime) {
+		foreach (glob($this->path . '*') as $filename) {
+			if (filemtime($filename) + $maxlifetime < time()) {
+				@unlink($filename);
+			}
+		}
+		return true;
+	}
+}
+
+$handler = new MySession2;
+session_set_save_handler(array($handler, 'open'), array($handler, 'close'),
+	array($handler, 'read'), array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc'));
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+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();
+
+session_set_save_handler($handler);
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+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();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: interface ***
+string(%d) "%s"
+string(4) "user"
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}
+string(%d) "%s"
+string(4) "user"
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}
+array(1) {
+  ["foo"]=>
+  string(5) "hello"
+}

Added: php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_002.phpt
===================================================================
--- php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_002.phpt	                        (rev 0)
+++ php/php-src/trunk/ext/session/tests/session_set_save_handler_iface_002.phpt	2012-01-04 01:16:45 UTC (rev 321738)
@@ -0,0 +1,90 @@
+--TEST--
+Test session_set_save_handler() function: interface wrong
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: interface wrong ***\n";
+
+interface MySessionHandlerInterface {
+	public function open($path, $name);
+	public function close();
+	public function read($id);
+	public function write($id, $data);
+	public function destroy($id);
+	public function gc($maxlifetime);
+}
+
+class MySession2 implements MySessionHandlerInterface {
+	public $path;
+
+	public function open($path, $name) {
+		if (!$path) {
+			$path = '/tmp';
+		}
+		$this->path = $path . '/u_sess_' . $name;
+		return true;
+	}
+
+	public function close() {
+		return true;
+	}
+
+	public function read($id) {
+		return @file_get_contents($this->path . $id);
+	}
+
+	public function write($id, $data) {
+		echo "Unsupported session handler in use\n";
+	}
+
+	public function destroy($id) {
+		@unlink($this->path . $id);
+	}
+
+	public function gc($maxlifetime) {
+		foreach (glob($this->path . '*') as $filename) {
+			if (filemtime($filename) + $maxlifetime < time()) {
+				@unlink($filename);
+			}
+		}
+		return true;
+	}
+}
+
+function good_write($id, $data) {
+	global $handler;
+	echo "good handler writing\n";
+	return file_put_contents($handler->path . $id, $data);
+}
+
+$handler = new MySession2;
+
+$ret = session_set_save_handler(array($handler, 'open'), array($handler, 'close'),
+	array($handler, 'read'), 'good_write', array($handler, 'destroy'), array($handler, 'gc'));
+
+var_dump($ret);
+$ret = session_set_save_handler($handler);
+var_dump($ret);
+
+session_start();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: interface wrong ***
+bool(true)
+
+Warning: session_set_save_handler() expects parameter 1 to be SessionHandlerInterface, object given in %s
+bool(false)
+good handler writing
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to