[Coding] PHP Variable Functions and Language Constructs
Posted by Khatharsis on January 21, 2013
Not quite aiming to start a weekly coding/PHP series, but I stumbled across another interesting topic while studying PHP interview questions yesterday (yes, I studied on Sunday). The question was simply, “What is the difference between the functions unlink() and unset()?” I have never used these functions before and had not had any reason to, but they are added to my arsenal and at least I know the concept/theory in case I ever do find a need for them.
The answer to this question is quite simple and even the PHP manual pages are brief. unlink() deletes a file while unset() destroys the specified variables. There’s a bit more to the process of each function and generally why I like the PHP manual is because users can contribute code bits or post about unexpected behavior.
unlink() deletes the file name, but not necessarily its contents. This may happen if a file has multiple links to it. I haven’t played around with this, but I get the impression it operates similarly to how Java’s garbage collector works. When an object no longer has any references to it, the garbage collector (which runs automatically and on its own time) will toss it out and free up the resources that object took. unlink() will destroy its connection to the file and if it is the only connection to that file, the file’s contents will be removed as well.
unset() is simpler by comparison, but it also has its own can of worms. unset() will destroy the specified variables, but there’s also a scope game involved. I’m taking the following examples from the PHP manual. If you attempt to unset a global variable inside of a function, the local copy of that global variable (i.e., the variable in the function) will be cleared but not the global variable itself. If you want to clear the global variable in a function, you would have to use unset() with the $_GLOBALS array. The same goes for a variable passed by reference: the local “copy” of variable is cleared, but not the variable itself. I don’t quite understand the reasoning for this as passing by reference ought to give the same variable, but it does not. Finally, using unset() with a static variable that is declared inside of a function will clear the local variable, but calling that function will restore the static variable’s previous value. I get the feeling a lot of interesting things can be done with this function alone once you understand its quirks. One user pointed out that if you unset the last element in a 1D array (e.g., index of 2), then add a new element to the array, it adds a new index (3) instead of replacing the index (2) that was unset.
Update (02/04/2013): While working on my dateDurationCalculator project, I ran into the problem of needing to unset a value in an array, then fix the indices for looping through the adjusted array later. Using array_values($arrayToReindex) and assigning the result back to the array (e.g., $arrayToReindex = array_values($arrayToReindex);) will fix it. See this post for more.
Okay, long explanation of the question aside, what caught my attention was a line towards the bottom of the unset() manual page: “Note: Because this is a language construct and not a function, it cannot be called using variable functions.”
What is a variable function? It’s simply a variable (e.g., $foo) that has parentheses appended to it (e.g., $foo()). PHP will look at the value of $foo (e.g., $foo = 'bar';) and try to find a function with the same name as its value (e.g., function bar()).
What is a language construct? It’s a reserved word in PHP’s language (similar to how JavaScript has a list of reserved words) that can look like a constant or function. As mentioned before, unset() is a language construct, but unlink() is not. Reserved words can be used as variables, but may cause confusion, especially when attempting to use it as a variable function. So when the note at the bottom of unset()‘s manual page says it cannot be called using variable functions, you can’t set a variable to the string ‘unset’ and attempt to use it or you will get the following error: “PHP Fatal error: Call to undefined function unset()”.
As a bonus to this post, I was very interested in the concept of the double dollar sign (e.g., $$b) or “variable variable”. It seems to work similarly to how variable functions work, but instead of searching for a function name, it will search for a variable name. For example:
$a = 'foo';
$$b = 'a';
echo $$b; //prints foo
Then, there a slight tweak to the variable variable:
$a = 'foo';
$$a = 'bar';
echo $foo; //prints bar
Note that I am using the same variable name ‘a’. What is happening here is $$a = 'bar' creates a variable $foo (because $a = 'foo') and sets the value of $foo to ‘bar’. It constructs a new variable rather than searches for the $bar variable. I imagine it can get very confusing in a larger code set with various variable names floating around. I am not sure when variable variables would be appropriate to use as it seems to be easier to use the variable itself than to set a floating variable to point to different variables as you need it.