The following code using switch and dynamic variables should return "b1" but it returns "11".
Is this a bug or am I doing something wrong?
<?php
$d = "Tuesday";
switch($d) {
case "Monday":
$$previousdayofmonthrow = "a";
$$previousdayofmonthcol = "7";
break;
case "Tuesday":
$$previousdayofmonthrow = "b";
$$previousdayofmonthcol = "1";
break;
case "Wednesday":
$$previousdayofmonthrow = "b";
$$previousdayofmonthcol = "2";
break;
case "Thursday":
$$previousdayofmonthrow = "b";
$$previousdayofmonthcol = "3";
break;
case "Friday":
$$previousdayofmonthrow = "b";
$$previousdayofmonthcol = "4";
break;
case "Saturday":
$$previousdayofmonthrow = "b";
$$previousdayofmonthcol = "5";
break;
case "Sunday":
$$previousdayofmonthrow = "b";
$$previousdayofmonthcol = "6";
break;
}
echo $$previousdayofmonthrow;
echo $$previousdayofmonthcol;
?>
Live example > http://codepad.org/wNfCqffD
tldr; It is not a bug in PHP related to dynamic variables, nor is it related with the switch statement.
The behavior of the test-case is correct and is well-defined, even if not expected.
This is because both $previousdayofmonthrow
and $previousdayofmonthcol
evaluate to undefined (did have notices enabled, no?) and thus both "dynamic variables" (aka variable-variable) expressions operate on the same variable.
Here is a minimal reproduction of the the behavior, without a switch, that also shows some interesting intermediate values:
$x = undefined; // The original doesn't set a value; it is implicitly undefined
$y = undefined; // but the effect is the same, and this way avoids warnings - yay!
$$x = "a";
echo $$x; // -> "a"
echo $$y; // -> "a"
$$y = "b";
echo $$x; // -> "b"
echo $$y; // -> "b"
This "linked" behavior occurs because, as previously stated, the variable-variable expression access the same variable - mainly the variable called "undefined". (The value of the expression used as the dynamic variable name is turned into a string and "" . undefined -> "undefined"
):
echo ${"undefined"}; // -> "b"
This "assignment of undefined" is allowed because undefined
in PHP is a reserved word - and not a constant/variable. Thus it is not prohibited to use "undefined" as a variable name even though it cannot appear as an unquoted identifier.
FWIW: Consider not using variable-variables; it is almost always better to use a discrete array when such "dynamic keys" are required.