I had an issue recently (PHP: variable value mysteriously set to 0) where a variable was being passed by value into a PHP function, and somehow the value of that variable was changed, like so:
$var = 'hello';
some_function($var);
echo $var; // outputs 0
It was hypothesized that it's an old function written in C and in its innards it was doing something to corrupt the variable, since in C apparently you can do that kind of thing. Anyway, I tried to copy the value first and then pass it in, like so:
$var = 'hello';
$var2 = $var;
some_function($var2);
echo $var; // Still outputs 0
Of course this didn't help, because, as I was reading here PHP is simply pointing $var2
in the symbol table to the same zval container as $var
and increasing that zval container's refcount. Of course, if $var2
is reassigned "by value", a new zval container should be created for it, but this was not a regular assign-by-value, apparently (there's a bit about this in the previous question with the __set()
magic method thing). I presumed that something was happening to the physical memory address at which the value was stored, rather than an assignment happening through the normal PHP machinery, and thus everything pointing to that zval would be affected. Very well.
My workaround was to find a way to clone the primitive $var
. Sorry if this is a repeat, but I found tons of stuff on cloning classes but nothing on cloning primitives, I think because PHP is supposed to be doing this properly automatically. I ended up using this:
$var = 'hello';
$serialized_var = serialize($var);
$var2 = unserialize($serialized_var);
some_function($var2);
echo $var; // Outputs 'hello', yay!
I'm just wondering, is there a better way? Let's presume that there's no other workaround, like using a different function or something, and that we have to get a true copy made of the variable. How could one go about it?