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.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I want to assign random profile pictures to users when they register on a website. I have a problem with my code. If I limit the "if and elseif" statements to 2 conditions, it works well. But when I go over 2 (in this case I have 10 conditions), the code doesn't work. If "switch" statement should be used instead, how would you write the code?
Here is my code
$rand = rand(1,10); //random number between 1 and 10
if($rand == 1)
$profile_pic = "/defaults/profile_pic1.png";
else if($rand == 2)
$profile_pic = "/defaults/profile_pic2.png";
.
.
.
else if($rand == 9)
$profile_pic = "/defaults/profile_pic9.png";
else
$profile_pic = "/defaults/profile_pic10.png";
I hope that's what you want
<?php
$rand = rand(1,10);
switch ($rand) {
case "1":
$profile_pic = "/defaults/profile_pic1.png";
echo "1";
break;
case "2":
$profile_pic = "/defaults/profile_pic2.png";
echo "2";
break;
case "3":
$profile_pic = "/defaults/profile_pic3.png";
echo "3";
break;
case "4":
$profile_pic = "/defaults/profile_pic4.png";
echo "4";
break;
case "5":
$profile_pic = "/defaults/profile_pic5.png";
echo "5";
break;
case "6":
$profile_pic = "/defaults/profile_pic6.png";
echo "6";
break;
case "7":
$profile_pic = "/defaults/profile_pic7.png";
echo "7";
break;
case "8":
$profile_pic = "/defaults/profile_pic8.png";
echo "8";
break;
case "9":
$profile_pic = "/defaults/profile_pic9.png";
echo "9";
break;
case "10":
$profile_pic = "/defaults/profile_pic10.png";
echo "10";
break;
default:
$profile_pic = "/defaults/profile_picDEFAULT.png";
echo "default PHOTO";
}
?>
I really do not understand why you would want to use a switch statement here. In terms of improving the code - you could go with only 2 lines. With if and switch it's 2-3 lines per condition and it's the worst programming practice you might come up with. Just give me a good reason why.
If you read PHP documentation thoroughly, there is the String Operators page available, which explains how your problem might be solved:
concatenation operator (.), which returns the concatenation of its right and left arguments.
$a = "Hello ";
$b = $a . "World!"; // now $b contains "Hello World!"
So you could simply do it with
$rand = rand(1,10);
$profile_pic = "/defaults/profile_pic" . $rand . ".png";
Or you might stumble upon Variable parsing, which states:
When a string is specified in double quotes or with heredoc, variables are parsed within it.
$juice = "apple";
echo "He drank some $juice juice.".PHP_EOL;
// Invalid. "s" is a valid character for a variable name, but the variable is $juice.
echo "He drank some juice made of $juices.";
// Valid. Explicitly specify the end of the variable name by enclosing it in braces:
echo "He drank some juice made of ${juice}s.";
So what you could do is:
$rand = rand(1,10);
$profile_pic = "/defaults/profile_pic${rand}.png";
If you are using the same random number in image path then no need for if or switch loop.
You can use below code.
$rand = rand(1,10) ;
$profile_pic = "/defaults/profile_pic$rand.png";
If you have mapping of random number and images then store it in array and access it.
$rand_image = array(1=>"firstimg.png", 2=>"2.png") ;
$profile_pic = "/defaults/profile_pic".$rand_image[$rand];
<?php
if (condition) {
code to be executed if this condition is true;
} elseif (condition) {
code to be executed if first condition is false and this condition is true;
} else {
code to be executed if all conditions are false;
}
?>
I have a large switch statement in my code, and I want it to do something like this:
// assign $foo
switch ($foo) {
case 1:
case 2:
// do X, then break if 1, do Y and break if 2
case 3:
case 4:
case 5:
// do A & B, break if 3, do C if 4 or 5, do D if 5 and then break
}
Such "groups" are prevalent throughout the switch statement and currently I just repeat the logic, keeping each case separate.
Am I wrong in assuming that this could be restructured into something that's objectively "better"?
Edit: I excluded my original code snippet from the question, since it had deeply flawed logic and didn't conform to the basic concepts of using a switch, replacing it with pseudocode that resembles the desired result.
As commented, that switch doesn't actually work as you think.
You're simply looking for:
if (in_array($foo, [1, 2])) {
...
if ($foo == 2) {
...
}
}
Alternatively:
switch ($foo) {
case 1:
case 2:
...
if ($foo == 2) {
...
}
break;
}
TLDR;
For simple "is it this", use a switch, if you need logical checks, use an if
The answer;
What you are asking is quite subjective, while using a switch for something simple is good, i.e;
<?php
$case = getCaseFrom("X"); // Let's say this = "a"
switch ($case)
{
case "a" : {
$thing = "a";
break;
}
case "b" : {
$thing = "b";
break;
}
case "c" : {
$thing = "c";
break;
}
default : {
$thing = "d";
}
}
?>
The same could be achieved by using;
<?php
$case = getCaseFrom("x");
$thing = $case;
// And even shorter;
$thing = getCaseFrom("x");
?>
Whereas, if you needed some logic to this...
<?php
$operator = getOperatorFrom("X"); // In this case, add
$num1 = 10;
$num2 = 2;
switch ($operator)
{
case "add" : {
$res = num1 + num2;
break;
}
case "subtract" : {
$res = num1 - num2;
break;
}
case "multiply" : {
$res = num1 * num2;
break;
}
case "divide" : {
$res = num1 / num2;
break;
}
}
?>
The alternative;
And of course, all of the above switches case be done using if else clauses, but a switch (IMO) is a neater, and more readable approach depending on what your certain criteria are (see the drawbacks).
The easiest way to look at it is;
If you need to check if something matches a value, use an if, if it is an enumerated set of values (let's say 1 to 4), a switch is subjectively better
The drawbacks;
A switch also doesn't let you have multiple "and" checks in the same statement, for example;
<?php
$case = getCaseFrom("X"); // In this case, a (does not have "b")
switch ($case)
{
case "a" :
case "b" : {
// This checks for a or b, not both, despite this not containing "b"
// this will still be accessed
break;
}
case "c" : {
// This will not be used as the break stops
// it from falling through to this clause
break;
}
}
if (stristr("a", $case) && stristr("b", $case))
{
// This checks to see if case contains a AND b
// therefore, this will not be used, as this
// does not have both a and b in $case
}
else if (stristr("a", $case) || stristr("b", $case))
{
// This checks to see if case contains a OR b
// therefore, this will be used, as this
// is checking that $case has "a" or "b" in it
// This is the same as the switch in this instance as it uses "or"
}
The noteworthy;
To be aware of the following also would be useful;
Inside a switches case, you cannot use login, for example;
case getThing("a") :
would cause an error
NB: Of course, when using the case statements, you don't need the curly braces added, they are mainly for code folding and ease of reading
Short question: WHY?!?
The below class returns ALL ALLRIGHT when calling:Status::validate('ab')
class Status
{
const FRESH = 0;
const PENDING = 25;
const CANCELLED = 50;
public static function validate($status)
{
switch ($status) {
case self::FRESH:
case self::PENDING:
case self::CANCELLED:
echo 'ALL ALLRIGHT';
default:
echo 'ERROR!';
}
die;
}
}
I believe it's because your $status is being casted to int.
$value = 'abc';
$other_value = '21abc';
echo (int)$value;
echo '<br>';
echo (int)$other_value;
Will return:
0
21
And that would cause it to think that ab value is equal to Status::FRESH
I'm not sure though if switch statement does this type of typecasting.
Edit
And I think I was right. More info here PHP Manual - switch.
Reference on typecasting strings to integers here PHP Manual - Strings.
break the case
switch($condition){
case "options": blah(); break;
}
In a webpage in top i use this code:
<?php
switch ($urlcomecatid) {
case "95":
$target_cat1='96';
$target_cat1_name = "A";
break;
case "96":
$target_cat1='95';
$target_cat1_name = "B";
break;
?>
and in another down part the page i use these variable
<?php
echo "<p class='pagefooterlifestyle' align='center'>
<a href='../lifestyle/lifestylesub.php? catid=$target_cat1'>$target_cat1_name</a></p>";
?>
BUT i get error undefined variable for
$target_cat1
$target_cat1_name
please let me know that what is the problem?
Initialize your variables:
switch ($urlcomecatid) {
case "95":
$target_cat1='96';
$target_cat1_name = "A";
break;
case "96":
$target_cat1='95';
$target_cat1_name = "B";
break;
default:
$target_cat1 = '';
$target_cat1_name = '';
}
You must be prepared for different values for $urlcomecatid as well.
If your $urlcomecatid variable contains neither 95 nor 96, PHP will ignore both cases, so the $target_cat1 and $target_cat1_name variables won't be initialized.
You can use default to tell PHP what to do when all cases are ignored.
http://php.net/manual/fr/control-structures.switch.php
here's some pseudo-code (it's not written correctly, the point of my ? is the variable, not the switch):
switch ($action) {
case "1":
//this is a function
case "2":
//this is a function
//etc.
}
How should this be written:
$variable = result of function in case 1.
Your switch statement is wrong . It requires a break keyword between every case
$action = 1;
$result = "Success";
switch ($action) {
case 1:
$variable = $result;
echo $variable;//prints Success
//this is a function
break; // like this
case 2:
//this is a function
break;//
//etc.
}
Just run the function(s) (you can pass args in too) as part of the code within the case / break blocks like this :
$action = 1;
switch ($action) {
case 1:
$variable = someFunctionOne();
break;
case 2:
$variable = someOtherFunctionTwo();
break;
//etc.
}
how to variable the result of php switch.
ex:
<?php
//variables of cases
$var_1 = 1;
$var_2 = 2;
$var_3 = 3;
$var_0 = 0;
//end variables of cases
//action variable
$action = 10;
//end action variable
//start switch
switch ($action) {
case "1":
echo "$var_1;";
break;
case "2":
echo "$var_2;";
break;
case "3":
echo "$var_3;";
break;
default:
echo "$var_0;";
}
//receives the value of the switch.
$switch_result = get_result_case;
//in this my example I need to enter the value of the case in a variable.
?>
in this my example I need to enter the value of the case in a variable.