> Intuitively, I would expect this:
>
> {
> let $x = new Foo;
> $x->bar();
> }
> somethingElse();
>
> to be equivalent to this:
>
> let $x = new Foo;
> $x->bar();
> unset($x);
> somethingElse();
If this feature freed variables when going out of scope,
it would be compiled more like the following (if there were multiple lets):
JavaScript doesn't have destructors, but PHP does, which makes the
implementation a tiny bit more complex.
```
try {
$x = new Foo();
$otherLet = new Other();
$x->bar();
} finally {
// try/finally is useful if unset($otherLet) could throw from __destruct
try {
unset($otherLet);
} finally {
unset($x);
}
}
somethingElse();
```
Actually, thinking about this again, performance is hopefully less of a concern.
I could safely avoid using `try/finally` if this was outside of a `try` block,
as long as this was in a function scope instead of a global scope.
(All variable go out of scope for uncaught exceptions)
This idea is still a work in progress.
It would definitely be useful to free immediately for objects (or arrays with
objects) which call `__destruct`
when the reference count goes to 0, such as RAII patterns.
My concern about adding an extra `unset()` is that it would add some
performance overhead,
discouraging using this feature, but opcache should be able to optimize the
unset out when unnecessary.
I touched on the reasons for avoiding `try` blocks earlier, but hopefully
they're not needed.
The global scope is less likely to be vital to performance in most cases.
> - Freeing it immediately would likely require the equivalent of a try{}
> finally{} to handle exceptions.
> try statements prevent opcache from optimizing a function, the last time I
> checked.
See
https://github.com/php/php-src/blob/43443857b74503246ee4ca25859b302ed0ebc078/ext/opcache/Optimizer/dfa_pass.c#L42-L49
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php