Hello, folks. If this is not the correct place to ask, I apologize.
TL;DR: Does setting a variable to
null
(or evenunset
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
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.
Hello, folks. If this is not the correct place to ask, I apologize.
TL;DR: Does setting a variable to
null
(or evenunset
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 assignnull
to the variables of typePdoStatement
.
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 evenunset
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
Hi Vinicius
TL;DR: Does setting a variable to
null
(or evenunset
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:
- 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. - = 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
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 script1. 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 programming2. 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.