> 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