Manual unset and GC

php.internals

Vinicius Dias

1 year ago
Hello, folks. If this is not the correct place to ask, I apologize.
> TL;DR: Does setting a variable to `null` (or even `unset`ing it) have **any** effect if that's the last instruction of a function?
The full version of the question with context: I have a question about the inner workings of PHP that was raised by some people at work. In the code we write at the company I work for, there's a guideline to always assign `null` to the variables of type `PdoStatement`. Something like the following: ``` $stm = null; ``` I understand this removes the reference to the object, calls the destructor and frees the memory, but the point is: the guideline mandates that we do that even if it is the last instruction of a function, for example: ``` function example(): void { // run your SQL queries $stm = null; } ``` I understand that this last line is not needed and removing it would have literally no effect on the code execution since `$stm` will go out of scope and the same things (remove reference, call destructor and free memory) will happen exactly the same. While discussing this with a few colleagues it was pointed out that **maybe** PHP will execute the GC immediately when we do `$stm = null` but not when the variable goes out of scope, making the explicit null as some sort of optimization. I didn't find any resources on the documentation that could point to which assumption is correct, so I post the question here: Does setting a variable to `null` (or even `unset`ing it) have **any** effect if that's the last instruction of a function? Thank you

Edmond Dantes

1 year ago
Hello! In modern PHP, the garbage collector (GC) is not a mandatory component, provided that the code is written without circular dependencies. As soon as an object loses its last reference (i.e., its reference count reaches zero), PHP immediately frees the resources. In this sense, you can think of PHP as similar to C++. Assigning NULL to a variable is essentially an explicit destruction of the reference. This can be useful in some cases, such as in a long-running application where the function scope will not be exited for a long time. However, in typical scenarios, it only clutters the code with an unnecessary instruction. --- Ed.

Derick Rethans

1 year ago
On 10 March 2025 16:15:16 GMT, Vinicius Dias <carlosv775@gmail.com> wrote:
>Hello, folks. If this is not the correct place to ask, I apologize. > >> TL;DR: Does setting a variable to `null` (or even `unset`ing it) have **any** effect if that's the last instruction of a function? > >The full version of the question with context: > >I have a question about the inner workings of PHP that was raised by >some people at work. > >In the code we write at the company I work for, there's a guideline to >always assign `null` to the variables of type `PdoStatement`. >Something like the following: > >``` >$stm = null; >``` > >I understand this removes the reference to the object, calls the >destructor and frees the memory, but the point is: the guideline >mandates that we do that even if it is the last instruction of a >function, for example: > >``` >function example(): void >{ > // run your SQL queries > > $stm = null; >} >``` > >I understand that this last line is not needed and removing it would >have literally no effect on the code execution since `$stm` will go >out of scope and the same things (remove reference, call destructor >and free memory) will happen exactly the same. > >While discussing this with a few colleagues it was pointed out that >**maybe** PHP will execute the GC immediately when we do `$stm = null` >but not when the variable goes out of scope, making the explicit null >as some sort of optimization. > >I didn't find any resources on the documentation that could point to >which assumption is correct, so I post the question here: > >Does setting a variable to `null` (or even `unset`ing it) have **any** >effect if that's the last instruction of a function? > >Thank you
No. It has no effect. At the end of the function PHP would remove a ref to the variable anyway. Setting it to null first is an action that will take time, unless opcache is turned on and realises it's a useless action. cheers Derick

Ilija Tovilo

1 year ago
Hi Vinicius On Mon, Mar 10, 2025 at 5:15 PM Vinicius Dias <carlosv775@gmail.com> wrote:
> > > TL;DR: Does setting a variable to `null` (or even `unset`ing it) have **any** effect if that's the last instruction of a function?
As others have pointed out, it is _almost_ completely unobservable. There are two small differences: 1. When the variable is a reference, $var = null; will write null to the reference, rather than the variable. The "out of scope cleanup" would be closer to an unset() rather than = null. 2. = null / unset() runs destructors in the scope of the child, while the cleanup on function exit executes in the parent scope. https://3v4l.org/obAgg But in terms of garbage collection, there's no value that would be cleaned up with an explicit unset() that wouldn't also be cleaned up when leaving the function. The arguments from your co-workers seem to rely on a faulty understanding of the engine. Ilija

Kamil Tekiela

1 year ago
Assuming that the variable gets created in the scope of the function and that it never leaks outside of the scope (e.g. by reference), then you can consider these things: PHP will destroy the object when there are no more references to it in the running script[1]. So, if the PDO object is limited to the function's scope, unsetting the variable, setting it to something else, or doing absolutely nothing will result in the same outcome. The code line `$stmt = null` doesn't directly affect the PDOStatement that was assigned to this variable previously. It just sets the value of the variable to something else. https://3v4l.org/VP5IJ Therefore, setting the variable to null as the last statement in the function is just adding an extra unnecessary line of code. I assume OPCache will optimize it away since it is dead code, but if not, then that's just one more operation PHP has to do as part of the function. From my testing, it seems the assignment is not optimized away. So it's the opposite of an optimization. The `$stmt = null` is cargo-cult programming[2]. Most likely, the developer that came up with this guideline learned PHP years ago when mysql_* API was in use. After switching to PDO, they realized there is no close() method and, without understanding why, tried to come up with an alternate "solution". Or maybe they've run into an issue with out-of-sync operations on MySQL and saw setting the variable to null as a quick solution. Later, people kept copying this code without knowing why that line was there. Neither the connection nor the statement should be closed. An attempt to do so is a code smell that indicates that your code is poorly designed and needs to be refactored. In your example, the refactoring involves simply removing the dead-code assignment. In other cases, it could mean restricting the objects only to the relevant scope. In my opinion, there isn't any good reason to unset a variable. [1]: https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.destructor [2]: https://en.wikipedia.org/wiki/Cargo_cult_programming