How to run a comparison within a string in php - php

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.

Related

save expression in variable php

I'm trying to store expression in variable and then use it in array_filter to return data based on this value for example
$condition = '== 100';
$test = array_filter($last,function ($data)use ($condition){
return $data['rating'] .$condition;
});
var_dump($test);
I tried to use html_entity_decode($condition, ENT_QUOTES); preg_replace( ) str_replace() as well as trim in order to remove the single quotes but it didn't work
I have many condition and I don't want to write array_filter many times is there a way to do this ? or better way then the one I'm trying to achieve.
I assumed that you have a limited number of comparison operators you are considering. For reasons of simplicity I numbered them 0,1,2,.... They will trigger different kinds of comparisons inside your filter callback function:
funcion myfiltarr($arr,$operator,$value){
$test = array_filter($last,function ($data) use ($operator, $value){
$v=$data['rating'];
switch($operator) {
case 0: return $v == $value;
case 1: return $v < $value;
case 2: return $v > $value;
case 9: return preg_match($value,$v);
// to be extended ...
default: return true;
}
});
return $test
}
$test=myfiltarr($last,0,100); // test: "== 100"
var_dump($test);
$test=myfiltarr($last,9,'/^abc/'); // test: "match against /^abc/"
var_dump($test);
Edit: I extended the original answer by a preg_match() option (comparison code: 9). This option interprets the given $value as a regular expression.

Conditional string i.e. '>' to an object i.e. >

$gted = (object)'>';
if(200 $gted 300){
echo 'wow it worked';
}else{
echo 'no it didnt work';
}
I am trying to convert the '>' to a conditional > to use in an if statement. Thanks.
This will not work the way that you have it. Variables cannot be be interpreted as operators in PHP directly, see also this question.
Even if you could interpret a variable as an operator, what you have in your string 'object' is not a greater-than sign, it is an HTML entity that, when interpreted as an HTML entity, yields something that looks like a greater-than sign.
This question has some answers that include some workarounds for arithmetic operators which can be used to store results to be evaluated inside of an if statement. As an example for use in this answer, I borrowed and slightly modified part of this answer by #user187291 that uses create_function:
$operator = '+';
$func = create_function('$a,$b', "return \$a $operator \$b;");
$result = $func(5, 1);
echo $result;
The echo'd result would be 6, as you would expect. You could change what operator is being used so that the pseudo-anonymous function instead returns a boolean value which you could then plug into an if statement:
$operator = '>';
$func = create_function('$a,$b', "return \$a $operator \$b;");
$result = $func(200, 300);
if($result) {
echo 'wow it worked';
} else {
echo 'no it didnt work';
}
Except in extreme and very specific circumstances that I cannot currently imagine, I would not think this to be a good idea.

Is it possible to have PHP if statement with all variables?

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!

Operator not working

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

PHP if condition with strings

I am trying to write would be a simple if condition.
function genderMatch($consumerid1, $consumerid2)
{
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1=$gender2)
echo 1;
return 1;
else
echo 0;
return 0;
}
The output of the getGender function is either a M or F. However, no matter what I do gender1 and gender2 are returned as the same. For example I get this output: MF1
I am currently at a loss, any suggestions?
if ($gender1 = $gender2)
assigns the value of $gender2 to $gender1 and proceeds if the result (i.e. the value of $gender2) evaluates to true (every non-empty string does). You want
if ($gender1 == $gender2)
By the way, the whole function could be written shorter, like this:
function genderMatch($cid1, $cid2) {
return getGender($cid1) == getGender($cid2);
}
You have to put two == for comparison. With only one, as you have right now, you are assigning the value to the first variable.
if($gender1=$gender2)
would become
if($gender1==$gender2)
this:
if($gender1=$gender2)
should be
if($gender1==$gender2)
notice the extra ='s sign. I think you might also need curly brackets for multiple lines of an if/else statement.
Your using the assignment operator = instead of comparsion operators == (equal) or === (identical).
Have a look at PHP operators.
You have some structural problems with your code as well as an assignment instead of a comparison.
Your code should look like this:
function genderMatch($consumerid1, $consumerid2){
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1==$gender2){
echo 1;
return 1;
}else{
echo 0;
return 0;
}
}
Notice the double '=' signs in the if statement. This is a comparison. A single '=' is an assignment. Also, if you want to execute more than 1 line of code with an if/else, you need brackets.
You are using a single = which sets the variable, ie. the value of $gender1 is set to be the value of $gender2.
Use the === operator instead: if($gender1 === $gender2). It is usually a good idea to do strict comparisons rather than loose comparisons.
Read more about operators here: php.net
Another alternative is to use strcmp($gender1, $gender2) == 0. Using a comparer method/function is more common in languages where the string-datatype isnĀ“t treated as a primary data-type, eg. C, Java, C#.

Categories