-
Notifications
You must be signed in to change notification settings - Fork 8k
Add support for arrays with object keys (WIP) #6588
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
wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip wip
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'd be interesting to know what the overall performance impact is when this is finished.
I'm not really sure how I personally feel about this yet - it's convenient to have the array copy-on-write semantics for a mapping from an object to a value (unlike SplObjectStorage where you have to explicitly clone) as well as to guarantee that the object won't expire (previously using $array[spl_object_id($node)] = $value )
(and the engine optimizations for that)
- e.g. ruby has symbols, python has a generic
dict(but both have a separate list)
But this would be less certain that a key of a known array could be converted to a string (PHP type hints don't go beyond array), that a constant expression could be json encoded, etc.
- e.g. false positives for
foreach ($key as $val) { echo $key . ":" . json_encode($val); }
Would $obj->{$obj2} = $value work? What's the plan for edge cases like $$obj = $value/extract/$GLOBALS work?
- objects as names for local/global variables doesn't have a good use case I can think of
- it may complicate generating backtraces (or even representations of constant arrays, in general) if code had
call_varargs(...[new stdClass() => true, Suit::Hearts => 7]);- json_encode would not be able to represent that, and may benefit from aJSON_SKIP_OBJECT_KEY|JSON_SKIP_NONSTRINGABLE_OBJECT_KEYflag
For unrelated reasons to this PR: Is it reasonable to assume that the pointer to a zend_object doesn't change (e.g. realloced) for the lifetime of an object (i.e. before it's garbage collected, even with reference count 1), are there exceptions to that rule?
(I've been assuming it is a safe assumption in an unrelated change I'm working on (e.g. zvals contain zend_object*, not a handle), but I'm not 100% certain. You'd be more familiar with that than me)
| _val = _z; | ||
|
|
||
| #define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \ | ||
| #define ZEND_HASH_FOREACH_ZKEY_VAL(ht, _key, _val) \ |
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.
Also adding macros for zend_long _h, zend_string *_key, zend_object *_obj might be easier from a migration standpoint for PECL code (the compiler could probably eliminate dead code if people backported that macro to php 8.0 and older)
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.
The ZKEY macros and functions are already intended to be polyfilled on older PHP versions. I've found that in most cases it's more convenient to keep the key as a zval rather than unpacking it, as most usages just pass through the key in some manner.
No, that would convert
This is safe to assume :) |
|
Something that may be helpful here: I am considering to try and introduce a magic method
This gives any object a default string representation. The distinction between Could this be helpful for cases like |
|
How does ksort() work when array keys are objects? |
|
I think it sorts by spl_object_id in this PR |
|
I do not like this RFC at all. It's adding even more complexity to arrays which are already doing many more things than they should. Also with this objects can be only used as keys if they're singletons. It's only a matter of time before another RFC (like 1 or 2) proposes something like an Equatable interface and this will cause BC break concerns because then it would make sense for two equatable objects should be treated as one key. What I'd be much more happy to see are specialized data structures with the ability to use objects as keys. Currently I'm very happy with using ext-ds for this - two objects can be considered the same using the Hashable interface. Please let arrays die in peace and come up with something better and faster to replace them with instead - providing new functionality like object keys there. |
|
@nikic are there any plans on picking this back up and submitting as RFC? I would love to see this in php 8.3. |
|
This wasn't finalized. Now it's outdated, so I'm closing this. |
Very much work in progress. A
--disable-allbuild mostly works.RFC: https://wiki.php.net/rfc/object_keys_in_arrays