Switch & Case multiple selections - php

I got an issue with switch.
Right now from my understanding it works like this:
if ( sizeof( $a ) !== sizeof( $types ) ) {
$type = $a[ 0 ];
switch ( $type ) {
case 'Red' :
$type = 'winered';
break;
case 'blue' :
$type = 'royalblue';
break;
case 'yellow' :
case 'lime' :
break;
case 'beige' :
$type = 'bright';
break;
default :
$type = get_option( 'my_option' );
break;
}
} else {
$type = get_option( 'my_option' );
}
So far so good. Whatever I select, it shows the case.
My issue is, it does it only one by one, I am able to select multiple cases like
case Red: case Blue:
$type = 'winered';
break;
But this won't work for me. In my scenario it is a checkbox I got case "Red" AND case "Blue" selected and want to display both "results": "winered" AND "royalblue". Right now it falls back to royalblue.
Any suggestions?
Thank you!

I dont think it is possible with a switch case to select multiple outcomes. I'd rather use an if statement something like:
if($type = 'red' || $type = 'blue'){
$type = 'winered';
$type = $type.'royalblue';
}

It doesn't really make sense why it would fall back to 'royalblue' other than:
'Red' != 'red', so it never really goes into the first case
Maybe this is how you have the types stored in $a, so that $a[0] is in fact 'blue', I would check that.
In any case, if you were interested in combination of different conditions, I would think that 'regular' if-then-else is the way to go. Case is generally faster, but offers itself for 'simpler' conditionals.
I hope this helps!

Your code is incomplete. However, I think the key is here:
$type = $a[ 0 ];
switch ( $type ) {
You only check the first value of $a. You can check all its values using a simple foreach:
// Put the selected values here; will join them at the end to get a string
$selected = array();
if (count($a) != count($types)) {
foreach ($a as $type) {
switch ($type) {
case 'Red':
$selected[] = 'winered';
break;
case 'blue':
$selected[] = 'royalblue';
break;
case 'yellow':
case 'lime':
// nothing here?!
break;
case 'beige':
$selected[] = 'bright';
break;
default:
$selected[] = get_option('my_option');
break;
}
}
} else {
$selected[] = get_option('my_option');
}
// Join the selected type with spaces
$type = implode(' ', $selected);

Related

Is there a more elegant way to execute this switch statement?

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

Can I use a strpos in a switch case?

Consider:
I have a variable called $field that from time to time may have, among others, values such as action, id, and another_term. I want to use a switch structure to sift the values:
switch ($field) {
case 'action':
// do something
break;
case 'id':
// do something
break;
case (strpos($field, '_term')):
// do something else
break;
}
The first two cases work. The third does not. I am thinking that this is an incorrect use of a switch statement. Is this better handled as an if/else sequence?
You can do it using the switch statement like this:
$field = 'bla bla_term bla';
switch (true) {
case $field === 'action':
echo 'action';
break;
case $field === 'id':
echo 'id';
break;
case strpos($field, '_term') >= 0:
echo '_term';
break;
}
The switch statement just compares the expressions in each case block to the value in the switch parentheses.
Expressions are units of code that you can reduce to a value, such as 2 + 3 or strpos(...). In PHP most things are expressions.
Here is an annotated version of the above example:
// We are going to compare each case against
// the 'true' value
switch (true) {
// This expression returns true if $field
// equals 'action'
case $field === 'action':
echo 'action';
break;
// This expression returns true if $field
// equals 'id'
case $field === 'id':
echo 'id';
break;
// This expression returns true if the
// return value of strpos is >= 0
case strpos($field, '_term') >= 0:
echo '_term';
break;
}
If you want to use the return value of the strpos call then you can just assign it (assignments are expressions in PHP):
case ($pos = strpos($field, '_term')) >= 0:
echo '_term at position ' . $pos;
break;
switch is just a sort of if x == y with y being any of the matching cases.
case (strpos($field, '_term')) would result in a -1 if match is not found or the point where "_term" was found (0 through string length -1 ) and not the field name.
If you're looking to catch anything with there phrase "_term" in the field do
$matches = array();
if(preg_match('/(.+)_term$/', $field, $matches)) {
$field = $matches[1];
}
this will replace the field value "address_term" or what ever "something_term" to just "address" or "something"

Can't get array_push working

I want to add values to an array so the output will be like this (1,2,3,4,5).
To accomplish this i tried to use array_push. I've tried a lot to get this working but it just outputs the last number which in this case is '5'. Do you guys see what is wrong with my code? Thanks in advance!
$websites = array();
case 'Hengelsport':
if ($waarde == 'true') {
array_push($websites,1);}
break;
case 'Diervoeders':
if ($waarde == 'true') {
array_push($websites,2);}
break;
case 'Vijverconcurrent':
if ($waarde == 'true') {
array_push($websites,3);}
break;
case 'Broqx':
if ($waarde == 'true') {
array_push($websites,4);}
break;
case 'Dekrabpaal':
if ($waarde == 'true') {
array_push($websites,5);}
break;
$this->articleData['website_ids'] = $websites;
You can't to have other value that last number, if you juste set $websites variable, like this : $websites = array();
And don't forget switch operator.
switch ($i) {
case "Hengelsport":
echo "i égal 0";
if ($waarde == 'true') {
array_push($websites,1);
}
break;
//...
}
Is it full code that you show us ?
Or for an easy way :
$website_ids = array(
'Hengelsport' => 1,
'Diervoeders' => 2,
'Vijverconcurrent' => 3,
'Broqx' => 4,
'Dekrabpaal' => 5
);
if ($waarde == 'true')
{
array_push($websites, $website_ids[$your_var_containing_name]);
}

How can I pass this variable and check if it matches?

How can I correct/simplify this and put it in an array?
A link is passing: somelink.php?w=a (or b,c,d)
I want the page (somelink.php) to determine if "w" is set, and if set and the var matches, include the specified page.
<?php
if(isset($_GET['w'])&&($GET['w'] == "a")){include("1.htm");}
if(isset($_GET['w'])&&($GET['w'] == "b")){include("2.htm");}
if(isset($_GET['w'])&&($GET['w'] == "c")){include("3.htm");}
if(isset($_GET['w'])&&($GET['w'] == "d")){include("4.htm");}
else{include("1.htm");}
?>
try using:
$w = $_GET['w'];
if(isset($w)) {
switch(strtolower($w)) {
case "a":
include("1.htm");
break;
case "b":
include("2.htm");
break;
case "c":
include("3.htm");
break;
case "d":
include("4.htm");
break;
default:
include("not-found.htm");
break;
}
}
Use a switch statement:
if(isset($_GET['w']))
{
switch($_GET['w'])
{
case 'a': include("1.html"); break;
case 'b': include("2.html"); break;
case 'c': include("3.html"); break;
case 'd': include("4.html"); break;
default: include("1.html"); break;
}
} else {
include("1.html");
}
how about a simple array
$x=array('a'=>'1.html','b'=>'2.html');
then
include $x[$GET['w']];
Like this:
if(isset($_GET['w'])){
switch($_GET['w']){
case "a":
include("1.htm");
break;
case "b":
include("2.htm");
break;
case "c":
include("3.htm");
break;
case "d":
include("4.htm");
break;
}
}
But I wouldn't do it that way. I'd make it so that the name of the page corresponds to the value being retrieved from the $_GET variable. That way you could do something like this.
if(!empty($_GET['w'])){
include($_GET['w'] . ".htm");
}
Of course, you'd want a little filtering of the $_GET var too to make sure it doesn't get something you don't want there. Maybe like this.
$acceptable_values = array("some","acceptable","values");
if(!empty($_GET['w']) && in_array($_GET['w'],$acceptable_values) ){
include($_GET['w'] . ".htm");
}
As I'm sure you are aware, passing variables directly into include statements or database queries is a TERRIBLE idea. See here for why in this case.
http://websec.wordpress.com/2010/02/22/exploiting-php-file-inclusion-overview/
You could do a few things, lets take a look at some of them.
<?php
$webpage = '';
if(isset($_GET['w']))
$webpage = strtolower($_GET['w']);
switch($webpage)
{
case 'b':
include '2.html';
break;
case 'c':
include '3.html';
break;
case 'd':
include '4.html';
break;
default:
include '1.html';
break;
}
Or we could use arrays
<?php
$webpage = '';
if(isset($_GET['w']))
$webpage = strtolower($_GET['w']);
$included_pages = array(
'a' => '1.htm',
'b' => '2.htm',
'c' => '3.htm',
'd' => '4.htm',
);
// Check inside our array
if(array_key_exists($webpage, $includes))
{
include $included_pages[$webpage];
}
else
{
// Couldn't find the site
include '1.htm';
}

Using conditional values from an array in an if...statement

I have an array of conditions :
$arrConditions = array ('>=2', '==1', '<=10');
...which I want to be able to use in an if...statement.
IE.
if (5 $arrConditions[0])
{
...do something
}
...which would be the same as :
if (5 >= 2)
{
...do something
}
Any help?
Thanks
Such a requirement is a sure sign of a bad design.
Most likely you can do that another, more usual way.
Nevertheless, never use eval for such things.
At least store each operator in pairs - an operator and operand.
$arrConditions = array (
array('>=',2),
array('==',1),
array('<=',10),
);
and then use switch:
list ($operator,$operand) = $arrConditions[0];
switch($operator) {
case '==':
$result = ($input == $operand);
break;
case '>=':
$result = ($input >= $operand);
break;
// and so on
}
But again - most likely you can solve it another, much easier way.
What about this ?
<?php
$arrConditions = array('==2', '==9', '==5', '==1', '==10', '==6', '==7');
$count = 0;
$myval = 0;
foreach ($arrConditions as $cond) {
$str = "if(5 $cond) { return $count;}";
$evalval = eval($str);
if (!empty($evalval)) {
$myval = $count;
}
$count++;
}
switch ($myval) {
case 0: echo '==2 satisfied';
break;
case 1: echo '==9 satisfied';
break;
case 2: echo '==5 satisfied';
break;
case 3: echo '==1 satisfied';
break;
case 4: echo '==10 satisfied';
break;
default : echo 'No condition satisfied';
}
?>

Categories