[PHP-CVS] [php-src] master: session: deprecate passing save handlers without create_sid() and validateId() methods

[email protected] (Gina Peter Banyard)
Newsgroups php.cvs
Message-ID <[email protected]>
Author: Gina Peter Banyard (Girgias)
Date: 2026-08-16T22:16:17+01:00

Commit: https://github.com/php/php-src/commit/6901c87aeabf28cbb08dadc2ac64d1dabfdfdd3c
Raw diff: https://github.com/php/php-src/commit/6901c87aeabf28cbb08dadc2ac64d1dabfdfdd3c.diff

session: deprecate passing save handlers without create_sid() and validateId() methods

RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_passing_a_sessionhandler_object_to_session_set_save_handler_which_does_not_contain_the_create_sid_and_validateid_methods

Changed paths:
  M  ext/session/mod_user_class.c
  M  ext/session/session.c
  M  ext/session/session.stub.php
  M  ext/session/session_arginfo.h
  M  ext/session/tests/user_session_module/gh9583-extra.phpt
  M  ext/session/tests/user_session_module/gh9583.phpt
  M  ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt
  M  ext/session/tests/user_session_module/session_set_save_handler_class_017.phpt
  M  ext/session/tests/user_session_module/session_set_save_handler_iface_001.phpt
  M  ext/session/tests/user_session_module/session_set_save_handler_iface_003.phpt


Diff:

diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c
index 9626dd27dfb1..6e30ed322378 100644
--- a/ext/session/mod_user_class.c
+++ b/ext/session/mod_user_class.c
@@ -158,3 +158,22 @@ PHP_METHOD(SessionHandler, create_sid)
 
 	RETURN_STR(id);
 }
+
+PHP_METHOD(SessionHandler, validateId)
+{
+	zend_string *id;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &id) == FAILURE) {
+		RETURN_THROWS();
+	}
+
+	PS_SANITY_CHECK;
+	if (!PS(mod_user_is_open)) {
+		php_error_docref(NULL, E_WARNING, "Parent session handler is not open, ignoring ID validation");
+		RETURN_TRUE;
+	}
+
+	zend_result status = PS(default_mod)->s_validate_sid(&PS(mod_data), id);
+
+	RETURN_BOOL(status == SUCCESS);
+}
diff --git a/ext/session/session.c b/ext/session/session.c
index b1f1d2a36304..a6e698d4c0aa 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -2158,6 +2158,9 @@ PHP_FUNCTION(session_set_save_handler)
 		} else if (zend_hash_find_ptr(object_methods, create_sid_name)) {
 			/* For BC reasons we accept methods even if the class does not implement the interface */
 			SESSION_SET_USER_HANDLER_OO(ps_create_sid, zend_string_copy(create_sid_name));
+		} else {
+			php_error_docref(NULL, E_DEPRECATED,
+				"Providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated");
 		}
 		zend_string_release_ex(create_sid_name, false);
 
@@ -2179,6 +2182,9 @@ PHP_FUNCTION(session_set_save_handler)
 			if (zend_hash_find_ptr(object_methods, validate_sid_name)) {
 				/* For BC reasons we accept methods even if the class does not implement the interface */
 				SESSION_SET_USER_HANDLER_OO(ps_validate_sid, zend_string_copy(validate_sid_name));
+			} else {
+				php_error_docref(NULL, E_DEPRECATED,
+					"Providing an object to argument #1 ($sessionhandler) which does not have the validateId() method defined is deprecated");
 			}
 			if (zend_hash_find_ptr(object_methods, update_timestamp_name)) {
 				/* For BC reasons we accept methods even if the class does not implement the interface */
@@ -2929,6 +2935,20 @@ static PHP_GINIT_FUNCTION(ps)
 	ps_globals->random_seeded = false;
 }
 
+static int session_handler_interface_gets_implemented(zend_class_entry *self, zend_class_entry *class) {
+	if (!zend_hash_str_exists(&class->function_table, ZEND_STRL("create_sid"))) {
+		zend_error(E_WARNING,
+			"Class %s implementing SessionHandlerInterface is missing the create_sid() method which will be required in PHP 9.0",
+			ZSTR_VAL(class->name));
+	}
+	if (!zend_hash_str_exists(&class->function_table, ZEND_STRL("validateid"))) {
+		zend_error(E_WARNING,
+			"Class %s implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0",
+			ZSTR_VAL(class->name));
+	}
+	return SUCCESS;
+}
+
 static PHP_MINIT_FUNCTION(session)
 {
 	zend_register_auto_global(zend_string_init_interned(ZEND_STRL("_SESSION"), true), false, NULL);
@@ -2947,6 +2967,7 @@ static PHP_MINIT_FUNCTION(session)
 
 	/* Register interfaces */
 	php_session_iface_entry = register_class_SessionHandlerInterface();
+	php_session_iface_entry->interface_gets_implemented = session_handler_interface_gets_implemented;
 
 	php_session_id_iface_entry = register_class_SessionIdInterface();
 
diff --git a/ext/session/session.stub.php b/ext/session/session.stub.php
index bfb6849f45e7..258715782d2c 100644
--- a/ext/session/session.stub.php
+++ b/ext/session/session.stub.php
@@ -147,4 +147,7 @@ public function gc(int $max_lifetime): int|false {}
 
     /** @tentative-return-type */
     public function create_sid(): string {}
+
+    /** @tentative-return-type */
+    public function validateId(string $id): bool {}
 }
diff --git a/ext/session/session_arginfo.h b/ext/session/session_arginfo.h
index 3860731a535a..dfcccc643410 100644
--- a/ext/session/session_arginfo.h
+++ b/ext/session/session_arginfo.h
@@ -1,5 +1,5 @@
 /* This is a generated file, edit session.stub.php instead.
- * Stub hash: 6bbbdc8c4a33d1ff9984b3d81e4f5c9b76efcb14 */
+ * Stub hash: 5109ef5c81733a112fe20d2626b8572d0969973c */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_session_name, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
 	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, name, IS_STRING, 1, "null")
@@ -135,6 +135,8 @@ ZEND_END_ARG_INFO()
 
 #define arginfo_class_SessionHandler_create_sid arginfo_class_SessionIdInterface_create_sid
 
+#define arginfo_class_SessionHandler_validateId arginfo_class_SessionHandlerInterface_destroy
+
 ZEND_FUNCTION(session_name);
 ZEND_FUNCTION(session_module_name);
 ZEND_FUNCTION(session_save_path);
@@ -164,6 +166,7 @@ ZEND_METHOD(SessionHandler, write);
 ZEND_METHOD(SessionHandler, destroy);
 ZEND_METHOD(SessionHandler, gc);
 ZEND_METHOD(SessionHandler, create_sid);
+ZEND_METHOD(SessionHandler, validateId);
 
 static const zend_function_entry ext_functions[] = {
 	ZEND_FE(session_name, arginfo_session_name)
@@ -221,6 +224,7 @@ static const zend_function_entry class_SessionHandler_methods[] = {
 	ZEND_ME(SessionHandler, destroy, arginfo_class_SessionHandler_destroy, ZEND_ACC_PUBLIC)
 	ZEND_ME(SessionHandler, gc, arginfo_class_SessionHandler_gc, ZEND_ACC_PUBLIC)
 	ZEND_ME(SessionHandler, create_sid, arginfo_class_SessionHandler_create_sid, ZEND_ACC_PUBLIC)
+	ZEND_ME(SessionHandler, validateId, arginfo_class_SessionHandler_validateId, ZEND_ACC_PUBLIC)
 	ZEND_FE_END
 };
 
diff --git a/ext/session/tests/user_session_module/gh9583-extra.phpt b/ext/session/tests/user_session_module/gh9583-extra.phpt
index 2193ab035df8..d82e0d8b2f0b 100644
--- a/ext/session/tests/user_session_module/gh9583-extra.phpt
+++ b/ext/session/tests/user_session_module/gh9583-extra.phpt
@@ -5,6 +5,8 @@ session
 --FILE--
 <?php
 
+ob_start();
+
 class SessionHandlerTester implements \SessionHandlerInterface
 {
 
@@ -42,6 +44,13 @@ echo 'validateId() ', (method_exists($obj, 'validateId') ? ('returns ' . ($obj->
 var_dump($originalSessionId == $newSessionId);
 
 ?>
---EXPECT--
+--EXPECTF--
+Warning: Class SessionHandlerTester implementing SessionHandlerInterface is missing the create_sid() method which will be required in PHP 9.0 in %s on line %d
+
+Warning: Class SessionHandlerTester implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0 in %s on line %d
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated in %s on line %d
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the validateId() method defined is deprecated in %s on line %d
 validateId() is commented out
 bool(true)
diff --git a/ext/session/tests/user_session_module/gh9583.phpt b/ext/session/tests/user_session_module/gh9583.phpt
index 24c1481eb7bb..040c2103d1e4 100644
--- a/ext/session/tests/user_session_module/gh9583.phpt
+++ b/ext/session/tests/user_session_module/gh9583.phpt
@@ -5,6 +5,8 @@ session
 --FILE--
 <?php
 
+ob_start();
+
 class SessionHandlerTester implements \SessionHandlerInterface
 {
 
@@ -38,6 +40,14 @@ echo "\n";
 
 ?>
 --EXPECTF--
+Warning: Class SessionHandlerTester implementing SessionHandlerInterface is missing the create_sid() method which will be required in PHP 9.0 in %s on line %d
+
+Warning: Class SessionHandlerTester implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0 in %s on line %d
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated in %s on line %d
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the validateId() method defined is deprecated in %s on line %d
+
 validateId() is commented out
 
 Session ID:%s
diff --git a/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt b/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt
index 61eecc7141d6..c31ffd935e32 100644
--- a/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt
+++ b/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt
@@ -80,6 +80,8 @@ array(1) {
   ["foo"]=>
   string(5) "hello"
 }
+
+Warning: SessionHandler::validateId(): Parent session handler is not open, ignoring ID validation in %s on line %d
 array(1) {
   ["foo"]=>
   string(5) "hello"
diff --git a/ext/session/tests/user_session_module/session_set_save_handler_class_017.phpt b/ext/session/tests/user_session_module/session_set_save_handler_class_017.phpt
index 6c1ecbe7e7ed..4556c5f26ad0 100644
--- a/ext/session/tests/user_session_module/session_set_save_handler_class_017.phpt
+++ b/ext/session/tests/user_session_module/session_set_save_handler_class_017.phpt
@@ -71,7 +71,7 @@ var_dump($_SESSION);
 <?php
 @unlink(session_save_path().'/u_sess_PHPSESSIDsession_set_save_handler_class_017');
 ?>
---EXPECT--
+--EXPECTF--
 *** Testing session_set_save_handler() function: class with create_sid ***
 string(34) "session_set_save_handler_class_017"
 string(4) "user"
@@ -79,6 +79,8 @@ array(1) {
   ["foo"]=>
   string(5) "hello"
 }
+
+Warning: SessionHandler::validateId(): Parent session handler is not open, ignoring ID validation in %s on line %d
 array(1) {
   ["foo"]=>
   string(5) "hello"
diff --git a/ext/session/tests/user_session_module/session_set_save_handler_iface_001.phpt b/ext/session/tests/user_session_module/session_set_save_handler_iface_001.phpt
index f25755dc3503..023680c4a5d4 100644
--- a/ext/session/tests/user_session_module/session_set_save_handler_iface_001.phpt
+++ b/ext/session/tests/user_session_module/session_set_save_handler_iface_001.phpt
@@ -83,6 +83,10 @@ session_unset();
 --EXPECTF--
 *** Testing session_set_save_handler() function: interface ***
 
+Warning: Class MySession2 implementing SessionHandlerInterface is missing the create_sid() method which will be required in PHP 9.0 in %s on line %d
+
+Warning: Class MySession2 implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0 in %s on line %d
+
 Deprecated: session_set_save_handler(): Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated in %s on line %d
 string(%d) "%s"
 string(4) "user"
@@ -94,6 +98,10 @@ array(1) {
   ["foo"]=>
   string(5) "hello"
 }
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated in %s on line %d
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the validateId() method defined is deprecated in %s on line %d
 string(%d) "%s"
 string(4) "user"
 array(1) {
diff --git a/ext/session/tests/user_session_module/session_set_save_handler_iface_003.phpt b/ext/session/tests/user_session_module/session_set_save_handler_iface_003.phpt
index 2bdb830296c2..66a813fa6637 100644
--- a/ext/session/tests/user_session_module/session_set_save_handler_iface_003.phpt
+++ b/ext/session/tests/user_session_module/session_set_save_handler_iface_003.phpt
@@ -70,8 +70,12 @@ var_dump($_SESSION);
 <?php
 @unlink(session_save_path().'/u_sess_PHPSESSIDsession_set_save_handler_iface_003');
 ?>
---EXPECT--
+--EXPECTF--
 *** Testing session_set_save_handler() function: id interface ***
+
+Warning: Class MySession2 implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0 in %s on line %d
+
+Deprecated: session_set_save_handler(): Providing an object to argument #1 ($sessionhandler) which does not have the validateId() method defined is deprecated in %s on line %d
 string(34) "session_set_save_handler_iface_003"
 string(4) "user"
 array(1) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.