I have a small switch statement in the header of a portfolio website I'm working on which governs which links are shown on which page. The value of $id comes from the GET variable, ie - '?id=index'.
switch($id) {
case "index":
//Show links to content
case !"index":
//Show link to index
case !"about":
//show link to about page
}
The issue is that the NOT operator isn't working in the final two cases. I want the link to the index to show when the user is NOT on the index page, and likewise with the about page. Currently, ALL links are shown on the index page (when $id == "index), and NONE are shown on any other pages.
Why might this be?
This is so, because it is supposed to be so.
switch compares using the == operator. So in the second case, you are actually testing whether
$id == (!"index")
Which will always evaluate to false since any string would be trueand not true would be false.
Which means, in your case it would be better to use if and else.
Sorry, but what you're trying to do is simply not valid syntax for a switch / case construct.
The closest you'll come to what you're looking for is to use the default option. This works like a final case option, that deals with all values that were not caught by any of the preceding cases.
switch($id) {
case "index":
//Show links to content
case "about":
//Show link to about page
default:
//show link to default page.
}
Also - don't forget the break; at the end of each case block, otherwise it'll fall through to the next one, which can lead to some unexpected bugs.
!"index" will probably evaluate as false (but I'm little surprised it didn't cause syntax error) and you'll actually having this statement:
switch($id){
case "index": //...
case false: // ...
case false: // ...
}
When you want to use switch, you'll need to do is this way:
switch($id){
case "index": // ...
case "about": // ...
default:
// Additional statements here, note that $id != "index" is already covered
// by not entering into case "index"
}
What your code is doing is comparing $id against three values: "index", !"index" (whatever it means) and !"about".
I'm not sure about your approach. You should try if/else or ternary operators.
Hope that it helps.
Switch doesn't offer custom operators.
switch ( $id ) {
case 'index':
// $id == 'index'
break;
case 'about':
// $id == 'about'
break;
case 'help':
case 'info':
// $id == 'info' or $id == 'help'
break;
default:
// all other cases
}
The switch case does not accept complex expressions. The not ! operator is a logical operator. It works in expressions like this.
!$x; // true if $x = false
or as a comparison operator:
$a != $b; // Not equal
// or
$a !== $b // not identical
From the manual.
The case expression of the switch statement may be any expression
that evaluates to a simple type, that is, integer or floating-point
numbers and strings. Arrays or objects cannot be used here unless they
are dereferenced to a simple type.
surely you can fix this with:
switch($id){
case ($id != 'index'):
echo 'this is not index';
break;
case 'index':
echo 'this is index';
break;
case 'foo':
echo 'this is foo!';
break;
default:
break;
}
However, this example is flawed, because the first case statement will just catch anything that isn't 'index' thus you shouldn't ever get to the case 'foo' nor the default statement
Related
Suppose I have an if statement in PHP, like this:
if($var || $var2 || $var3){
//code
}
How do I know which variable triggered the if statement?
You don't.
If you must know, you need a conditional on each one.
if ($var1) {
// Do someting
} elseif ($var2) {
// Do something else
} // etc...
Alternatively, if you have several conditions you want to check in this manner, you can hijack a switch for this purpose:
switch(true) {
case $var1:
// Do something
break;
case $var2:
// Do something else
break;
// etc.
}
It is possible only if you change a little your way to think
$data=7;$data2=false;$data3='';
if($filter=array_filter(compact('data','data2','data3'))){
echo key($filter);//output data
}
A little explanation :
first we compact all variables in one array with the compact function
second we filter the array with the array_filter function
At this step all is done.if $filter is empty the if condition will be evaluated to false and if $filter is not empty it means that at least one of the variable is different of false or null or empty string
Then to know the one of this variable which triggered the if you can check the $filter array specially the first element.
I would suggest using a switch statement instead of an if statement.
switch ($var) {
case "content of var1":
code to be executed if $var = "content of var1";
break;
case "content of var2":
code to be executed if $var = "content of var2";
break;
case "content of var3":
code to be executed if $var = "content of var3";
break;
...
default:
code to be executed if $var is something else;
}
Note that everything inside the quotes "" is a string and therefore should be whatever your $var1, $var2, or $var3 are likely to contain.
Also note that in this example, there is only one $var and it stores different content depending on the situation.
I have a switch statement with 3 cases,like this:
switch($date) {
case 1:
echo "";
break;
case 2:
echo "";
break;
case 3:
echo'';
break;
default:
echo '';
break;
}
And i am wondering,if there is a way to loop through all cases if they are all true.But with using break,because if i am not using it,the cases wont work properly.So is there a way???
You shouldn't use switch if you want to see if multiple things are true about the variable in question since the switch statement will cut out once one of the cases holds true (i.e. it won't continue to look to see if the other cases also apply to the variable).
If your goal is to test if multiple things are true regarding a variable, just use an if statement:
if ($date == X && $date == Y && $date == Z) {
// Do something since all the conditions are met
}
Another possibility is to "fall through" your cases like this:
switch ($variable) {
case 0:
// Do something to (some) variable to indicate this case applies
case 1:
// Do something to (some) variable to indicate this case also applies
case 2:
// Do something to (some) variable to indicate this case also applies
echo "WHATEVER YOU WANT TO ECHO"
break;
}
I use javascript to send cases to and ajax function. The cases are taken from the link id. For example, if user clicked this link:
<a id="answer-yes-123">click this</a>
The javascript will split the id to 3 part, and send the middle part "yes" to ajax as a case. For most cases, when ajax receives the case, if yes do this if no do that.
switch ($case) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
There's one exception-- a numerical case. If the middle part of the link is a number, I don't know how to make the switching statement. There are potentially unlimited different numbers, I can't make each of them a case, How to make a condition like if(is_int($case)) to work as a case?
In the switch default: case, you can test is_int():
switch ($case) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
default:
// Determine the numeric value however you need to
// is_int(), is_numeric(), preg_match(), whatever...
if (is_int($case)) {
// numeric stuff
}
}
This is a little strange logically, because default: is typically used for the do this if nothing else is met condition. In your case though, if you don't need to further divide the numeric case much it works. Just be sure to comment it clearly in your code so you remember why you did it when you look back on it in six months.
Update after comments:
Since you already used the default:, I believe you can actually use an expression inside a case. This warrants even clearer commenting since it is not a common practice and goes kind of against the purpose of a switch:
switch ($case) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
// This actually works, but is highly weird.
// One of those things I can't believe PHP allows.
// is_int(), is_numeric(), preg_match(), whatever...
case is_int($case):
// Numeric stuff
break;
default:
// default stuff
}
Write the if-statement around the switch.
Something like this comes to my mind:
if (is_int($case)) {
// ...
} else {
switch ($case) {
// ...
}
}
Michael Berkowski's answer is perfect, but if don't want to use default case like this that could work also:
switch (preg_replace('/^[0-9]*$/','numeric',$case)) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
case 'numeric' :
$assignment->remove();
break;
default:
//...
break;
}
Use PHP's is_numeric
http://php.net/manual/en/function.is-numeric.php
if (is_numeric($case)) {
// ...
} else {
switch ($case) {
// ...
}
}
In PHP I'd like to do this:
switch (function_foo($bar,$bar2)) {
case $fu:
*Do Stuff*
break;
case $fubar:
*Do Other Stuff*
break;
}
Is this a terrible idea? Will it work?
Using a function in the switch is OK : the function will be called, and will return a value -- which is the one that will be used for the case.
It's exactly the same as writing :
$my_var = function_foo($bar,$bar2);
switch ($my_var) {
// ...
}
Even if I prefer using a variable, so the code is easier to read.
And using variables in the case is something you don't see often ; but it works fine too ;-)
Quoting the manual page of switch :
The case expression may be any
expression that evaluates to a simple
type, that is, integer or
floating-point numbers and strings.
So, your code will work, as long as $fu and $fubar contain simple-type values.
Using a variable as a case value not often done (as far as I can tell from the code I read), probably because some other languages don't allow that (for instance, C doesn't allow that ; and the switch/case structure is borrowed from C) ; but it works :
$a = 1;
$b = 2;
switch (1) {
case $a: echo 'a'; break;
case $b: echo 'b'; break;
}
Will output :
a
Never tried a function as parameter to the switch, not sure (You should give it a try), however you can first store function return value in some variable and use that in switch eg:
$return_value = function_foo($bar, $bar2);
switch ($return_value) {
case $fu:
*Do Stuff*
break;
case $fubar:
*Do Other Stuff*
break;
}
According to the manual, a PHP switch statement is exactly like a series of if/else if statements (if every case ends with break). That means your technique should work. As long as the function names and variable names are readable, I can't think of any problems with it.
In some other languages, the switch statement is actually a performance improvement over if/else if statements, so you need to know the case values at compile time. It doesn't look like PHP does that kind of thing.
Its posibble yes and its called lambda, which are hidden functions
$lambda = function($a, $b) {
return $a * $b;
};
$return_value = function foo($bar, $bar2){ return $logic }
switch ($lambda(2,4)) {
case $fu:
*Do Stuff*
break;
case $fubar:
*Do Other Stuff*
break;
}
echo empty($location);
switch($location){
case (empty($location)):
expression 1;
break;
case ($location%10000==0):
expression 2;
break;
case ($location%100==0):
expression 3;
break;
default:
expression 4;
break;
}
When I echo empty($location), it prints out 1, why is expression 1 not executed?
You're not using switch statements properly. The way they work is to compare each case value against the initial switch value.
In your case, let's pretend $location = null;
echo empty($location); // true: null is considered empty.
switch ($location) {
case empty($location) : // this performs the check:
// $location == empty($location)
// null == true ==> false
so that's why it doesn't run..
I'd recommend sticking to if .. else in this case.
The empty function returns a boolean value of 1 or 0 http://uk3.php.net/empty
Whereas the switch / case statements check whether a variable holds a certain value and execute an expression depending on that
In you case, expression 1 should be executed if the value of $location==1 (you effectively asked for that when you typed switch($location)),
So the logic of your above code is:
if $location==1, execute expression 1
if $location%10000==0, execute expression 2
etc. etc.
is the value of $location==1?
A switch statement is not the same as an if/else statement. Switch statements are looking for specific values. If it finds the value specified in a given case statement, it runs the code after that case statement.
The following code:
switch($x)
case 1:
// some stuff
break;
case 2:
// some other stuff
break;
default:
// some more stuff
break;
Is the equivalent of this code:
if($x == 1){
// some stuff
}
elseif($x == 2){
// some other stuff
}
else{
// some more stuff
}
Basically, switch statements are shortcuts for if/elseif/else blocks where you're checking for a single variable's equality against a bunch of possibilities.
Since empty() returns 0 or 1, your first case will run if $location is 1 (if $location is empty) or 0 (if $location isn't empty). It's almost like you've written the following:
elseif($location == empty($location)){ ...
Make sense? Instead of using a switch statement, you probably want the following:
if(empty($location)){
// ...
}
elseif($location % 10000 == 0){
// ...
}
// ...