-
Notifications
You must be signed in to change notification settings - Fork 7.9k
RFC: Locked Classes #3931
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
RFC: Locked Classes #3931
Conversation
An instance of a locked class may not: - have properties added that were not declared - have properties read that were not declared - have properties unset
@@ -266,6 +266,9 @@ typedef struct _zend_oparray_context { | |||
/* Children must reuse parent get_iterator() | | | */ | |||
#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 17) /* X | | | */ | |||
/* | | | */ | |||
/* Class is declared "locked" | | | */ | |||
#define ZEND_ACC_LOCKED (1 << 18) /* X | | | */ |
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.
Since this constant will be exposed to userland (via ReflectionClass::IS_LOCKED
), whereas most of these aren't, such a high number might seem surprising to users, but I'm not sure of the impact of rearranging this list.
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.
We don't make any particularly guarantees about the values of those flags in reflection (in fact, they change between releases). I wouldn't worry about this.
@@ -0,0 +1,40 @@ | |||
--TEST-- | |||
A sub-class of a locked class is not locked unless explciitly marked |
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.
A sub-class of a locked class is not locked unless explciitly marked | |
A sub-class of a locked class is not locked unless explicitly marked |
This proposal has been withdrawn. See the RFC for details of why. |
While performing resource -> object migrations, we're adding defensive classes that are final, non-serializable and non-clonable (unless they are, of course). This path adds a ZEND_ACC_NO_DYNAMIC_PROPERTIES flag, that also forbids the creation of dynamic properties on these objects. This is a subset of #3931 and targeted at internal usage only (though may be extended to userland at some point in the future). It's already possible to achieve this (what the removed WeakRef/WeakMap code does), but there's some caveats: First, this simple approach is only possible if the class has no declared properties, otherwise it's necessary to special-case those properties. Second, it's easy to make it overly strict, e.g. by forbidding isset($obj->prop) as well. And finally, it requires a lot of boilerplate code for each class. Closes GH-5572.
Initial implementation of "locked classes", as described in https://wiki.php.net/rfc/locked-classes
Included tests all pass, but there may be situations I have not considered, or other places that will need changing.