Simple question really. I have come across an issue with work where it would be ideal to store >= <= and == into a variable to spit out into certain if statements wherever the case may be.
$numb1 = 5
$numb2 = 10
$option = >=
if($numb1 $option $numb2)
You can't put a var for testing this in a control instruction.
This will return some : syntax error, unexpected T_VARIABLE
You could use some eval() to do it, but it's not advisable.
Perhap's you could make something different with the following :
$option=$_GET['option']; // or POST or something else...
$numb1 = 5;
$numb2 = 10;
switch($option) {
case ">=":
if($numb1 >= $numb2){//someting}
break;
case "<=":
if($numb1 <= $numb2){//someting}
break;
case "==":
if($numb1 == $numb2){//someting}
break;
default://something else if there is no $option
break;
}
Or with a function like the following
function testVar($numb1,$numb2,$option)
{
// Same switch
}
Not without using eval() which is generally considered a bad idea
Doing it directly like that, will only work using eval() - Using eval is not considered good practice. The main problem being that if the eval() statements takes in user input the user can inject php into your code. That's obviously bad. Refer this thread - When is eval evil in php?
What you'd be better off doing is created a series of switch statements for all the various operations such as 'greater than', 'less than', 'equals' and so forth...
The best thing to do for this is to make a function call or object wrapper, and then call the function to achieve the same result.
Example:
$func = '__my_eq_op_';
if ($func($numb1,$numb2)) {
// Do stuff
}
The operator functions are then...
function __my_eq_op($a,$b) {
return $a == $b;
}
function __my_gte_op($a,$b) {
return $a >= $b;
}
function __my_lte_op($a,$b) {
return $a <= $b;
}
For example. So you can really just break it down into using the functions instead.
For this:
if ($x == $y)
The parser sees 6 tokens...
1) KEYWORD IF:
2) LPAREN
3) VAR X
4) EQ
5) VAR Y
6) RPAREN
The parser uses these tokens to construct the AST for the IF conditional. Your thinking needs to move away from seeing the "==" as a variable. It's an operator!
Related
If I have:
$compare = "5<6";
How do I look at the compare variable and return the value true. The input needs to be a string so taking away the " won't help. The string could be very complex so I'm looking for a function already in PHP which can run this, or something that someone has written before which can do this. I've tried the eval() function but that doesn't work, so:
$compare = "5<6";
echo eval($compare);
just errors. Thanks for your help in advance.
Using code evaluation functions are something that should be discouraged, because it may lead to a lot of security problems, but if you want to keep your logic that way, you must evaluate a valid code:
<?php
$compare = "5 > 6";
eval("\$result = $compare;");
var_dump($result);
Your comparing stringmust be used inside the eval function like it would be done in the normal code, not expecting a return value. So what I changed in this sample code is that I used a variable named $result to store the value from the evaluated code.
As you will see when running this code, the $result will be a boolean value (false in this sample, because 5 is not greater than 6, obviously).
Try this:
<?php
$compare = "5<6";
eval('$output = '.$compare.';');
echo $output;
?>
From PHP documentation: http://php.net/manual/en/function.eval.php
Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
You can display with echo directly:
<?php
$compare = '5<6';
echo $compare. "\n";
echo eval("return $compare;");
?>
Or You can store result in variable to display later:
<?php
$compare = '5<6';
echo $compare. "\n";
$result = eval("return $compare;");
echo $result;
?>
Be careful ;)
If you wanted to avoid eval it's easy enough to parse comparison expressions. Just split the string on a comparison operator and return the result of the corresponding comparison.
function compare($expr) {
$expr = preg_split('/(>=|<=|<|>|=)/', $expr, -1, PREG_SPLIT_DELIM_CAPTURE);
list($lhs, $op, $rhs) = $expr;
switch ($op) {
case '<': return $lhs < $rhs;
case '<=': return $lhs <= $rhs;
case '>': return $lhs > $rhs;
case '>=': return $lhs >= $rhs;
case '==': return $lhs == $rhs;
}
}
Apparently I missed the bit about "the string could be very complex" when I read the question initially, so this may not be helpful in your case, but I'll leave it here for future reference.
I understand whiles, ifs, fors, cases, arrays, functions, and other syntactic constructs and my coding experience is 70’s style Fortran and T-SQL.
Now I’m trying to understand PHP, but it occasionally seems to compress several statements into one obfuscating line of code. What’s the expanded equivalent of the following single line of PHP below?
$start = gt("start") === false ? 0 : intval(gt("start"));
It is a ternary operator. They're usually of the following format:
expr1 ? expr2 : expr3;
Which means:
if expr1 then return expr2 otherwise return expr3
It can be visualized as follows:
Your code can be rewritten as:
if (gt("start") === false) {
$start = 0;
} else {
$start = intval(gt("start"));
}
It can improved as follows, to avoid an extra function call:
if (($result = gt("start")) === false) {
$start = 0;
} else {
$start = intval($result);
}
This ? is known as the ternary operator. It is a shorthand, e.g.
$x = a ? $b : $c; // where 'a' is some expression, variable or value
could also be written:
if (a) {
$x = $b;
}
else {
$x = $c;
}
Essentially, if expression a evaluates equal to TRUE, then the ternary operator returns b, otherwise it returns c.
Others have posted answers that do a good job of explaining the basics of how a ternary operator works, but to visualize what a ternary is versus an if/else you can do the following. Look at your example:
$start = gt("start") === false ? 0 : intval(gt("start"));
Now let’s make it one line using if/else:
if (gt("start") === false) { $start = 0; } else { $start = intval(gt("start")); }
When you see it lined up like that the immediate take-away—beyond the basic structure—is you must set $start = within each conditional.
So knowing that, them main benefit of a ternary operator is quick if/else logic to assign a value to a single variable.
The convenience of this from a coding standpoint is one can quickly disable that logic by just commenting out one line while debugging instead of having to comment out multiple lines of an if/else.
I have found something weird...,
I have this piece of code at the end of my function:
return $class == 3?"red":$class==2?"orange":$class==1?"yellow":"";
Now, when $class == 2 this returns "yellow" and not "orange" like I expected.
Can someone explain this to me?
You need to use parentheses as ternary operators are left-associative in PHP. Associativity is how "operators of the same precedence are grouped in the absence of parentheses" - from Operator Associativity
$class == 3?"red":($class ==2?"orange":($class ==1?"yellow":""));
This is because it is treated like it was:
return (($class == 3?"red":$class==2)?"orange":$class==1)?"yellow":"";
So add brackets to force the right use:
return $class == 3?"red":($class==2?"orange":($class==1?"yellow":""));
I would never code it like that. I believe that when you are coding, you really want to see immediately what a piece of code is doing. This won't do that, this is just giving you headaches ;-)
Maybe change it to something clear:
switch($class) {
case 1:
return 'yellow';
case 2:
return 'orange';
case 3:
return 'red';
default:
return '';
}
use parentheses:
$class = 2;
echo $class == 3?"red":($class==2?"orange":($class==1?"yellow":""));
Output : orange
I have a operator in a string .
$c['operator'] = ">=";
if($sub_total.$c['operator'].$c['value'])
{
echo $sub_total.$c['operator'].$c['value'];
}
it obtain output is 20610>=30000
I'd put the possible operators in a switch:
$result = null;
switch($c['operator'])
{
case '>=':
$result = $sub_total >= $c['value'];
break;
case '<=':
$result = $sub_total <= $c['value'];
break;
// etc etc
}
This is far safer than using eval, and has the extra benefit that it sanitises the input.
$sub_total.$c['operator'].$c['value'] is not a comparison but a string concatenation. A filled string is always true in PHP, hence the if-statement is always true.
String can't be interpreted as php code unless you use eval (be careful with it).
What you are doing in your example in if statement is that you concatenate strings and because string after concatenation is not null it's evaluated to true, so if statement is executed.
In your case solution would be to see which operator is used like #adam has written in his solution.
BTW, having logic in strings (and possibly outside of script) is not a good idea.
Use PHP eval to evaluate the code you constructed.
$c['operator'] = ">=";
if(eval($sub_total.$c['operator'].$c['value']))
{
echo $sub_total.$c['operator'].$c['value'];
}
You can't do that in PHP, you should do something like below :
if ($c['operator'] == '>=' and $sub_total >= $c['value']) {
// Do something
} else if ($c['operator'] == '<=' and $sub_total <= $c['value']) {
// Do something else
} // etc...
Take a look at the eval method. It's very dangerous though
http://php.net/manual/en/function.eval.php
Im not great in php and I could do with a little help. I want to say something like
if ($x == 1 or 2 or 3 or 4) {do function}
but the only way i know how to do that is to go
if (($x == '1') or ($x == '2')) or...
which seems a long way of doing it. Is there a better way I am missing, like
if ($x == 1,2,3,4) {do}
Thanks for your answers!
you can use in_array function
$array = array(1,2,3,4)
if(in_array($x, $array)) {
// do something
}
switch ($x) {
case 1:
case 2:
case 3:
case 4:
// do
break;
}
Or you can use the in_array() function creating an array such as $a = array(1,2,3,4); and then do if (in_array($x, $a)).
If you are concerned about space, you can also use the shortcut:
if (in_array($x, array(1,2,3,4))) { /* do */ }
You can create an array of expected values and then use function in_array().
http://php.net/manual/en/function.in-array.php
If it's a range, you could do:
if ($x >= 1 && $x <= 4) { }
You could also construct an array and check if the number is in that array.
<?php
$data = array(1,2,3,4);
if(in_array($x, $data)){
// execute function
}
?>
All the above ideas are good. I am going to show another way, that is not better, but is different.
You can store comparations in variables, to use later or combine. This helps readability, and make complex expresions easy to create and read. It obviusly remove any repetition.
$is_number = ($str=="one" or $str=="two" or $str=="tree");
$is_english = ($str=="one" or $str=="horse");
$is_french = ($str=="baguette" or $str=="amie");
$is_fun = $is_french or $is_english;
if($is_french and !$is_number){ ... }