0

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

user2864740
  • 60,010
  • 15
  • 145
  • 220
Gary Carlyle Cook
  • 728
  • 11
  • 26
  • Use `$` instead of `$$`. It will give `b1` – MH2K9 Sep 06 '14 at 03:04
  • @user3659034 `$` should give him nothing as nothing is set on it. – Prix Sep 06 '14 at 03:07
  • @Prix you are correct! I suggested him according to his question! Thank you. – MH2K9 Sep 06 '14 at 03:09
  • I don't know why I got a downvote? I am learning and this gave me a kind of false-positive. – Gary Carlyle Cook Sep 06 '14 at 03:14
  • Agree with the advice here. Turn on error reporting, and minimize your code to try to isolate and reproduce what you believe is a bug. Often times, when you're doing your homework before asking a question you'll realize your own error in the process and not need to ask a question at all. – Chris Baker Sep 06 '14 at 03:54
  • I asked IF it was a bug or am I doing something wrong. For coders there is a lack of understanding the condition in my words it seems and I dont see how that is begging a bug and even if it is its not clear enough that is seen as wrong here. I didnt know it was. – Gary Carlyle Cook Oct 11 '14 at 22:33

1 Answers1

3

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.

user2864740
  • 60,010
  • 15
  • 145
  • 220