I've got 3 variables:
$left_side = "'Username'";
$equation = "==";
$right_side = "'Username'";
I want to test these variables as it was an if statement like so:
if($left_side $equation $right_side) {
// do something
} else {
// do something else
}
I know this works:
if(eval("return ".$left_side." ".$equation." ".$right_side.";")) {
// do something
} else {
// do something else
}
I always tought it's 'not good' to use eval. Especially when you try to run user input.
Is there an other way to do this? I tried to google it, but it's not my friend to day ;)
You may do something like this:
function testValues($val1, $equation, $val2) {
$res = false;
switch($equation) {
case "==":
$res = $val1 == $val2;
break;
case ">":
$res = $val1 > $val2;
break;
//....
default:
throw new Exception("Unknown operator");
}
return $res;
}
and than use it like:
if(testValues($left_side,$equation,$right_side)) {
//do something
} else {
//do something
}
eval is evil. And no, there's no other (easy) solution, but maybe this one helps:
if ($equation == "==") {
if ($left_side == $right_side) {
// ... your code goes here.
} else {
// Do some other stuff.
}
}
You could use switch:
$left_side = "'Username'";
$equation = "doublequal";
$right_side = "'Username'";
switch($equation){
case 'doublequal':
if ($left_side == $right_side) {
// code
}
break;
//......
}
You should never use eval() especially with user input.
eval() is evil, but call_user_func() is evil too and every framework uses this function in one place or another.
Tools aren't evil. They are just tools. Evil is the way that we use them.
As Uncle Ben said: Great power involves great responsibility :)
I find this trick
http://gonzalo123.com/2012/03/12/how-to-use-eval-without-using-eval-in-php/
the idea is create a temporary file with the PHP source code, include this file with the standard PHP’s include functions and destroy the temporary file.
Related
I am in the making of some code that needs to check if a users login details are correct, and I therefore need a lot of if-statements inside each other. If any of the conditions in the if-statements are not true, they should alle return the same value. Is there an easy way of doing this, instead of writing the same multiple times? I have made an example below to visualize my problem. As you can see here I write " else { return false; }" multiple time, and this is what I am wondering if you are able to do more efficiently. Maybe so I only have to write "or else return false" once.
//some code
if (/*some condition*/) {
//some code
if (/*some new condition*/) {
//some code
if (/*some new condition*/) {
//some code
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
I am having a hard time finding a good way to explain my problem, so if you have a more elegant way of explaining it, do not hesitate to edit my post. I am also not quite sure that the title is as good as it could be, so if you have any ideas to an alternativ please say so :)
Lets say you have something like that (I added No):
if ( condition1 ) {
//some code 1
if ( condition2 ) {
//some code 2
if ( condition3 ) {
//some code 3
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
Since each time a condition is false, you exit the function returning false, you can directly test if the condition is false using a negation (if the negated condition is true):
if ( !condition1 ) {
return false;
}
//some code 1
if ( !condition2 ) {
return false;
}
//some code 2
if ( !condition3 ) {
return false;
}
//some code 3
This doesn't reduce the number of if statements, but you avoid many nesting levels and the else statements.
You can also try the switch statement. For many situations it will produce cleaner code.
<?php
if ($i == 0) {
echo "i equals 0";
} elseif ($i == 1) {
echo "i equals 1";
} elseif ($i == 2) {
echo "i equals 2";
}
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
}
?>
The switch statement is also compatible with using strings:
<?php
switch ($i) {
case "apple":
echo "i is apple";
break;
case "bar":
echo "i is bar";
break;
case "cake":
echo "i is cake";
break;
}
?>
Good luck! :)
in PHP (and even other languages but in the present case this is more for PHP), i often end up sometimes having to code long conditions such as the example below:
i have a code with many conditions and i want to display a different result based on certain conditions.
if something is RED and the other thing is RED, then print X,
if something is RED but the other thing is BLACK, then print Y
if something RED and the other thing is RED but a third thing is blue, then print X
& so on
is there a way to properly handle this by using some kind of data structure/configuration array/matrix/whatever ? that is, storing these "conditions" and "results" properly in some kind of configuration array or other ?
instead of having to code nested conditions that can be tricky to support afterwards
like this very small example but in a much bigger scale
if (preg_match(/something/, $string) {
$result = 'GREEN';
} elseif (preg_match(/something/, $string) {
$result = 'RED';
} else {
if (something else) {
$result = 'GREEN';
} else {
if (something OR something) {
$result = 'AMBER';
} else {
$result = 'GREEN';
}
}
}
or is it the only way of handling this ?
maybe with a single
if (something and something or something) {
} elseif (something and something and something) {
} elseif (something and something or something and something) {
} etc
thank you for your help
i'm coding an app that should display a different "status" for a certain data depending on many different data (other attributes of this data), and i'd like to avoid having unreadable code
You can use nested arrays:
$conditions = [
'/something1/' => [
'/something2/' => "X"
],
'thing3' => [
'/thing3/' => 'Y',
'/thing4/' => 'Z'
]
];
$matched = false;
foreach ($conditions as $key1 => $val1) {
if (preg_match($key1, $string)) {
if (is_array($val1)) {
foreach ($val1 as $key2 => $val2) {
if (preg_match($key2, $string)) {
$result = $val2;
$matched = true;
break;
}
}
} else {
$result = $val1;
$matched = true;
}
}
if ($matched) {
break;
}
}
if (!$matched) {
$result = 'default';
}
To allow arbitrary levels of nesting you could turn this into a recursive function.
For the purposes of the answer below I'm assuming you're coding OO PHP.
One variable
When I have one variable that determines the outcome, if the variable is boolean or close to being boolean (meaning it can only either be one or two different values), is to use an if() statement like you have. If the variable can be a variety of (known) values, like your colours example, I use a switch() function.
Two or more variables
If I have two variables that determine the outcome, for instance colour and size, I first use a switch(), then for each switch, I use a method that contains another switch().
It may be more verbose, but it is so much easier to keep track of in the long run. Below is a simplified example of the logic.
switch ($colour) {
case 'red':
red_handler($size);
break;
case 'green':
green_handler($size);
break;
case 'blue':
blue_handler($size);
break;
}
/** We already know the first variable value is red */
function red_handler($size)
{
switch ($size) {
case 'small':
echo "my fruit is a cherry";
break;
case 'medium':
echo "my fruit is an apple";
break;
case 'large':
echo "my fruit is a watermelon";
break;
}
}
In a similar vein to #dearsina i'd tend to separate it out into functions for this kind of thing, for example if you know there are lots of cases where it could return the same value, e.g.:
if(isGreen($string)) return 'GREEN';
else if (isRed($string)) return 'RED';
function isGreen($string) {
if(cond1)return true;
if(cond2 && cond3)return true;
if(cond4 || cond 5)return true;
return false;
}
function isRed($string) {
if(cond6)return true;
if(cond1 && cond7)return true;
if(cond2 || cond 8)return true;
return false;
}
we do sometimes use the style you've suggested...
if (something and something or something) {
} else if (something and something and something) {
but you can quickly end up back in the same problems of readability and maintenance issues
If I want to create an if statement with 2 variables:
if ($variable1 && $variable2) {
// Do something
}
And then add another if statement below with only the first variable, how would I do it? Do I only include the one variable like this:
else if ($variable1) {
// Do something
}
Or do I need to specify that the first variable is true, not the second? If so, is this correct?
if ($variable1 && !$variable2) {
// Do something
}
Go for:
if ($variable1 && $variable2) {
// Do something
}
else if ($variable1) {
// Do something
}
the reason is for example if you write like this :
the following is wrong approach
if ($variable1) {
// if u have two variables $variable1 and $variable2
// and you want to validate both but if the $variable1 contains
// nonzero value it will never go to the else part
}
else if ($variable1 && $variable2) {
// Do something
}
now basically
else if ($variable1) {
// Do something
}
and
else if ($variable1 && !$variable2) {
// Do something
}
are same.you can use any of them if you are not toooo much concerned about the performance.
else if ($variable1) {
// Do something
}
is enough. Since the first if-statement will fail, it will evaluate the else if as a new statement
I have this code being used on my website
if( isset($_GET['gw'] )){
//this is some content
}
So whenever my url is something like this
http://mywebsite.com/?gw=hello
the content inside that div will appear. It works very well, but now what I want to do is have different content for a specific string. Something like this
if (gw=hello) {
// content here
} else if (gw=goodbye) {
// content here
} else {
//content here
}
I know that is not the code, but does anyone know a way I could do this? Thanks!
Your pretty much there!
if(isset($_GET['gw'])) {
if($_GET['gw'] == "hello") {
}
else if ($_GET['gw'] == "goodbye") {
}
else {
}
}
It's probably best to use a switch statement, so you can easily expand on the conditions in the future.
switch (isset($_GET['gw']) ? $_GET['gw'] : '')
{
case "hello":
// do something here
break;
case "goodbye":
// do something here
break;
default:
// default action if nothing above matches
break;
}
Let's take a look at the following code:
if ($a == 1) {
echo "this is stage 1";
}
else if ($a == 2) {
echo "this is stage 2";
}
else if ($a == 3) {
$a = 1;
// at this point I want something that restarts the if-else construct so
// that the output will be "this is stage 1"
}
I'm working on an if else construct at the moment and let's say that I have three stages and the if-else construct checks which stage I'm in.
Now it happens that some activities in stage 3 lead to a jump back to stage 1. Now I've already passed the code for stage one, which is why I want to somehow restart the if-else construct. Is there a way to do that? And even more important: Is there a better way to do what I want? Because my idea doesn't seem to be good practice.
You're right, it's bad practice.
You're asking for goto.
Example:
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
The above would never output 'Foo'
It's difficult to suggest the better method without seeing exactly what you're trying to do, but consider a switch.
switch ($a) {
case 3:
// Execute 3 stuff
// No break so it'll continue to 1
case 1:
// Execute 1 stuff
break // Don't go any further
case 2:
// 2 stuff
break;
}
That's probably not what you want either.
You may just want to abstract the code into functions and call them multiple times if necessary.
You can put an endless loop around your if and break out if you're done
while (1) {
if ($a == 1) {
echo "this is stage 1";
break;
}
else if ($a == 2) {
echo "this is stage 2";
break;
}
else if ($a == 3) {
$a = 1;
}
else {
break;
}
}
Maybe you want to look at Wikipedia - Finite-state machine and this question PHP state machine framework
The short answer is yes, there is a way, but the better answer is yes to your second question as well.
Put, at very least, the code that can get called from multiple locations in a function. For example,
function stageOneCode() {
//do stuff;
}
etc.. I would recommend a function for each stage, but it's hard to make recommendations without actually seeing what's being executed in the stages.
In any event, at the end of your stage three function, simply call your stage one function.
A recursive function is helpful for this (but maybe overkill if it will always revert back to 1)
function echo_stage($stage) {
if ($a == 1) {
return "this is stage 1";
}
else if ($a == 2) {
return "this is stage 2";
}
return echo_stage(1);
}
echo echo_stage(5);
Or:
switch ($number)
{
case 2 :
echo "this is stage 2";
break;
case 1:
default:
echo "this is stage 1"
}
use switch(). you can have a "default" case as well as specific cases.
A loop is what you are searching for:
// initialize $a
$a = 1;
// the while loop will return endless
while (true);
// if you want to break for any reason use the
// break statement:
// if ($whatever) {
// break;
// }
if ($a == 1) {
echo "this is stage 1";
}
else if ($a == 2) {
echo "this is stage 2";
}
else if ($a == 3) {
$a = 1;
// continue will go back to the head
// of the loop (step 1) early:
continue;
}
// don't forget to increment $a in every loop
$a++;
}