I have a function:
$query = "SELECT * from lol";
database_query( $query );
considering the $query will never be changed inside the database_query function, is it good practice to use a pointer to $query so the function doesn’t need to assign more memory to a new iteration of the value passed in?
function database_query( &$query ){
//do stuff that does not affect $query
}
This turns out to be a very interesting question, I’ve spent the last hour and a half reading about PHP and how it handles references (thank you Tim Cooper for the links that got me started).
To answer your question, yes – it’s good practice to use a reference like that when you call a function. By using a reference you will use fewer resources – there is no "copy on write" for a reference variable. Here’s some proof:
If you copy/paste the above code into a PHP page and execute it you will see this:
So what we have here is four basic tests. I create a global variable ($a) and assign it the value of 5.
When I call the noref_nowrite function we see that XDebug counts 3 references while PHP’s built in function counts 4. Interestingly, PHP optimizes this so internally it’s really like calling the ref_nowrite function because PHP makes $var_a a reference to $GLOBALS[‘a’].
When I call the noref_write function we see that the refcount drops to 1 (or 2 if you look at PHP’s built-in function). Why? Because this is where the "copy on write" issue takes place. Up until we incremented $var_a PHP was internally using $var_a as a reference to $a but when we changed the value we forced PHP to make a copy of the variable so it could be incremented. So at that point $var_a was no longer a reference to $a, instead it was changed to reference it’s own data.
The ref_nowrite function shows ambiguous results. Looking at it alone we can’t prove anything. However the ref_write function shows us that XDebug says we’re dealing with a reference variable (is_ref=1) and most importantly we see that after we increment $var_a the value of our global variable $a has also changed – this means $var_a and $GLOBALS[‘a’] are definitely pointing at the same place in memory. Which means changing $var_a did NOT trigger a "copy on write" situation – and it shouldn’t since we’re dealing with a reference.
Play around with this to convince yourself and here’s some more reading:
Detecting whether a PHP variable is a reference / referenced (I thought ircmaxell had a well thought out answer)
https://www.php.net/debug-zval-dump
XDebug documentation: http://xdebug.org/docs/display
PHP What References Do: https://www.php.net/manual/en/language.references.whatdo.php
PHP Reference Counting Basics: https://www.php.net/manual/en/features.gc.refcounting-basics.php