Skip to content

Commit 126b3e5

Browse files
committed
Implement a POC for spl_object_id(object $x) : int
https://github.com/runkit7/runkit_object_id is a C module which implements the same functionality (Without obfuscation) Pending question: Can `sizeof(zend_long)` be > `sizeof(intptr_t)` - If so, detect that condition at compile time and return a binary string with that many bytes, instead. Also, can two PHP "object"s have the same object id, but different object handlers? (E.g. iterator of a class) - If that is so, then document if this case is possible, but keep behaving the same way.
1 parent 99b6119 commit 126b3e5

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

ext/spl/php_spl.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,14 +794,32 @@ PHP_FUNCTION(spl_object_hash)
794794
}
795795
/* }}} */
796796

797+
/* {{{ proto int spl_object_id(object obj)
798+
Return integer hash id for given object */
799+
PHP_FUNCTION(spl_object_id)
800+
{
801+
zval *obj;
802+
803+
ZEND_PARSE_PARAMETERS_START(1, 1)
804+
Z_PARAM_OBJECT(obj)
805+
ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL());
806+
807+
RETURN_LONG(php_spl_object_id(obj));
808+
}
809+
/* }}} */
810+
811+
static void php_spl_init_hash_mask() {
812+
SPL_G(hash_mask_handle) = (intptr_t)(php_mt_rand() >> 1);
813+
SPL_G(hash_mask_handlers) = (intptr_t)(php_mt_rand() >> 1);
814+
SPL_G(hash_mask_init) = 1;
815+
}
816+
797817
PHPAPI zend_string *php_spl_object_hash(zval *obj) /* {{{*/
798818
{
799819
intptr_t hash_handle, hash_handlers;
800820

801821
if (!SPL_G(hash_mask_init)) {
802-
SPL_G(hash_mask_handle) = (intptr_t)(php_mt_rand() >> 1);
803-
SPL_G(hash_mask_handlers) = (intptr_t)(php_mt_rand() >> 1);
804-
SPL_G(hash_mask_init) = 1;
822+
php_spl_init_hash_mask();
805823
}
806824

807825
hash_handle = SPL_G(hash_mask_handle)^(intptr_t)Z_OBJ_HANDLE_P(obj);
@@ -811,6 +829,20 @@ PHPAPI zend_string *php_spl_object_hash(zval *obj) /* {{{*/
811829
}
812830
/* }}} */
813831

832+
PHPAPI zend_long php_spl_object_id(zval *obj) /* {{{*/
833+
{
834+
intptr_t hash_handle;
835+
836+
if (!SPL_G(hash_mask_init)) {
837+
php_spl_init_hash_mask();
838+
}
839+
840+
hash_handle = SPL_G(hash_mask_handle)^(intptr_t)Z_OBJ_HANDLE_P(obj);
841+
842+
return (zend_long) hash_handle;
843+
}
844+
/* }}} */
845+
814846
int spl_build_class_list_string(zval *entry, char **list) /* {{{ */
815847
{
816848
char *res;
@@ -915,6 +947,10 @@ ZEND_END_ARG_INFO()
915947
ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_object_hash, 0, 0, 1)
916948
ZEND_ARG_INFO(0, obj)
917949
ZEND_END_ARG_INFO()
950+
951+
ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_object_id, 0, 0, 1)
952+
ZEND_ARG_INFO(0, obj)
953+
ZEND_END_ARG_INFO()
918954
/* }}} */
919955

920956
/* {{{ spl_functions
@@ -931,6 +967,7 @@ const zend_function_entry spl_functions[] = {
931967
PHP_FE(class_implements, arginfo_class_implements)
932968
PHP_FE(class_uses, arginfo_class_uses)
933969
PHP_FE(spl_object_hash, arginfo_spl_object_hash)
970+
PHP_FE(spl_object_id, arginfo_spl_object_id)
934971
#ifdef SPL_ITERATORS_H
935972
PHP_FE(iterator_to_array, arginfo_iterator_to_array)
936973
PHP_FE(iterator_count, arginfo_iterator)

ext/spl/php_spl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ PHP_FUNCTION(class_implements);
7171
PHP_FUNCTION(class_uses);
7272

7373
PHPAPI zend_string *php_spl_object_hash(zval *obj);
74+
PHPAPI zend_long php_spl_object_id(zval *obj);
7475

7576
#endif /* PHP_SPL_H */
7677

0 commit comments

Comments
 (0)