-
Notifications
You must be signed in to change notification settings - Fork 208
PHPC-1849: Handle deprecation of Serializable in PHP 8.1 #1246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
86ae7c3
to
b3d1920
Compare
These methods will be used on PHP 7.4+ when available. Implementing them is required to suppress a deprecation notice on PHP 8.1+. This commit also renames is_debug parameter for get_properties_hash utility functions (and related macros) to more accurately reflect its purpose of allocating a new HashTable instead of using an internal props table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good, just a couple of questions on the code to judge potential refactoring effort.
{ | ||
zval data, type; | ||
|
||
ZVAL_STRINGL(&data, intern->data, intern->data_len); | ||
zend_hash_str_update(props, "data", sizeof("data") - 1, &data); | ||
|
||
ZVAL_LONG(&type, intern->type); | ||
zend_hash_str_update(props, "type", sizeof("type") - 1, &type); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've wondered about this before. What's the practical reason for nesting? Is it to only conditionally allocate the two zval
structs on the stack and avoid doing so if there's no data to handle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These aren't even conditionally allocated. We're just using braces to create a scope and allow us to declare variables inline. Our C compiler options would otherwise flag this as a warning and require that we declare these at the top of the function scope.
ZEND_BEGIN_ARG_INFO_EX(ai_Binary___unserialize, 0, 0, 1) | ||
ZEND_ARG_ARRAY_INFO(0, data, 0) | ||
ZEND_END_ARG_INFO() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been wondering about this for a while as well: shouldn't this be in PHP's realm to provide arginfo structs for its own interface? We're duplicating this in a lot of our classes, where using ai_Serializable___unserialize
would work just fine everywhere else 🤔
// cc @nikic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting point, although I could see this being problematic if PHP happened to change its arginfo between versions. I think this may relate to why interfaces in 8.1 started using tentative return types, to defer the actual changes to PHP 9.0.
Allowing extensions to define their own arginfo presumably lets us use a narrower API if we want, which would still conform with the interface in core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays we auto-generate all arginfo (as well as class declarations in general) anyway, so we don't have any particular interest in making reuse simpler.
ZVAL_STRING(&ref, intern->ref); | ||
ZVAL_STRING(&id, intern->id); | ||
zend_hash_str_update(props, "ref", sizeof("ref") - 1, &ref); | ||
zend_hash_str_update(props, "id", sizeof("id") - 1, &id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to change anything here, but getting to the second class in the code review I thought "I suppose this is now 20 times the same change", and I immediately catch the different code organisation between this and the Binary class up there. No need to change since I'd like to refactor this code in general: macros that call the combination of ZVAL_*
and zend_hash_str_update
would help since they could handle the scoping (if it's necessary, see earlier comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created PHPC-1962 to track this.
/* {{{ proto void MongoDB\Driver\DBPointer::__unserialize(array $data) | ||
*/ | ||
static PHP_METHOD(DBPointer, __unserialize) | ||
{ | ||
zval* data; | ||
|
||
PHONGO_PARSE_PARAMETERS_START(1, 1) | ||
Z_PARAM_ARRAY(data) | ||
PHONGO_PARSE_PARAMETERS_END(); | ||
|
||
php_phongo_dbpointer_init_from_hash(Z_DBPOINTER_OBJ_P(getThis()), Z_ARRVAL_P(data)); | ||
} /* }}} */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this is another one where I feel PHP could offer a macro:
/* {{{ proto void MongoDB\Driver\DBPointer::__unserialize(array $data)
*/
IMPL_SERIALIZABLE___UNSERIALIZE_START()
php_phongo_dbpointer_init_from_hash(Z_DBPOINTER_OBJ_P(getThis()), Z_ARRVAL_P(data));
IMPL_SERIALIZABLE___UNSERIALIZE_END() /* }}} */
Since the other logic is always the same, this may be an improvement to help reducing the menial task of adding this to multiple classes...
|
||
echo throws(function() { | ||
unserialize('O:19:"MongoDB\BSON\Binary":1:{s:4:"data";s:6:"foobar";}'); | ||
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know many of these files don't do this yet, but we should be using the ::class
constant. No need to change this in these files as they're most likely copypasta from the originals, so I'll see if I can do a nice find/replace to take care of these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would likely require a sprintf
since we'd also need to capture the string length in the preceding integer. I'll leave this to you to make a ticket if you'd like to track the work.
Noted one test failure on AppVeyor for 32-bit CursorId |
https://jira.mongodb.org/browse/PHPC-1849