From 7486849b562bfe1d9a04a79c5aba00edb88d3bbf Mon Sep 17 00:00:00 2001 From: Arpad Ray Date: Wed, 4 Jan 2012 01:16:45 +0000 Subject: [PATCH] add SessionHandlerInterface for session_set_save_handler() - #60551 --- ext/session/php_session.h | 3 + ext/session/session.c | 29 ++++- .../session_set_save_handler_iface_001.phpt | 113 ++++++++++++++++++ .../session_set_save_handler_iface_002.phpt | 90 ++++++++++++++ 4 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 ext/session/tests/session_set_save_handler_iface_001.phpt create mode 100644 ext/session/tests/session_set_save_handler_iface_002.phpt diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 40924e5c7b..ba0195bec4 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -274,6 +274,9 @@ void php_session_shutdown(void *data); #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); diff --git a/ext/session/session.c b/ext/session/session.c index a52a62ba77..b1224321a6 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -67,6 +67,9 @@ static int (*php_session_rfc1867_orig_callback)(unsigned int event, void *event_ /* SessionHandler class */ zend_class_entry *php_session_class_entry; +/* SessionHandlerInterface */ +zend_class_entry *php_session_iface_entry; + /* *********** * Helpers * *********** */ @@ -1598,8 +1601,8 @@ static PHP_FUNCTION(session_set_save_handler) 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, ®ister_shutdown) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, php_session_iface_entry, ®ister_shutdown) == FAILURE) { + RETURN_FALSE; } /* Find implemented methods */ @@ -1673,7 +1676,6 @@ static PHP_FUNCTION(session_set_save_handler) 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 @@ static const zend_function_entry session_functions[] = { }; /* }}} */ -/* {{{ 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 @@ static PHP_MINIT_FUNCTION(session) /* {{{ */ 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); diff --git a/ext/session/tests/session_set_save_handler_iface_001.phpt b/ext/session/tests/session_set_save_handler_iface_001.phpt new file mode 100644 index 0000000000..c8199ffe31 --- /dev/null +++ b/ext/session/tests/session_set_save_handler_iface_001.phpt @@ -0,0 +1,113 @@ +--TEST-- +Test session_set_save_handler() function: interface +--INI-- +session.save_handler=files +session.name=PHPSESSID +--SKIPIF-- + +--FILE-- +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" +} diff --git a/ext/session/tests/session_set_save_handler_iface_002.phpt b/ext/session/tests/session_set_save_handler_iface_002.phpt new file mode 100644 index 0000000000..42e8fbe3fd --- /dev/null +++ b/ext/session/tests/session_set_save_handler_iface_002.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test session_set_save_handler() function: interface wrong +--INI-- +session.save_handler=files +session.name=PHPSESSID +--SKIPIF-- + +--FILE-- +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 -- 2.40.0