Re: Possible RFC: UniqueInterface that throws exception at refcount > 1
| From: | tyson andre | Date: | Sat, 11 Jul 2020 14:55:46 +0000 |
| Subject: | Re: Possible RFC: UniqueInterface that throws exception at refcount > 1 | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-110943@lists.php.net to get a copy of this message | ||
> Yes, it would be a dynamic uniqueness system, kind of.
>
> Another more flexible alternative would be to add magic methods at
> refcount = 1 and refcount > 1, possibly __owned() and __shared(int
> $refcount), for classes that implement a TrackReferencesInterface or
> similar. But this would need to do ~0 performance hit if not used,
> don't know if possible.
Then again, php already calls __destruct if it exists when the refcount goes to 0,
so I may be overestimating the potential performance impact.
There's a lot of edge cases - probably way more than I mention here.
Running into those edge cases, you might find the feature unsatisfactory if it were to be
implemented.
For example,
- The UniqueReferenceException itself creates a trace, that increments reference counts, which might
itself cause a UniqueReferenceException.
Workarounds for that would probably involve allowing multiple objects to reference a
UniqueInterface, and then it would be a weaker guarantee.
- unserialize() keeps extra references to ensure that it can delete the created objects if the
original references were overwritten. __wakeup() and __unserialize()
- The reference count is incremented when calling __destruct(), I think.
```
<?php
class UniqueObject implements UniqueInterface{
public function __construct() {
debug_zval_dump($this); // refcount 3 - and then what about
$GLOBALS['something'] = $this inside __construct
}
public function someUtilMethod() {
// object(UniqueObject)#1 (0) refcount(2){
// }
debug_zval_dump($this);
}
}
// The reference count goes to 2 in someUtilMethod because there's 2 references.
// the temporary and $this.
(new UniqueObject())->someUtilMethod();
```
- Tyson