Php : how to evaluate string to operator? - php

I have 3 variables :
$a = 5;
$b = 3
$o = "*";
The $o variable contains a string value. This value can also be "/", "+", "-".
So when I concatenate $a.$o.$b :
$result = $a.$o.$b;
echo $result;
The result is 5*3 (a string) instead of 15.
So how to convert operator string into real operator ?

You can't, you'd need to make a function or a switch statement to check each of the operators.
Read this question and its answers so you'll understand how to do it.

Actually you can do it, by using eval. But it hurts to recommend using eval, so I just give you a link to another question with a good answer: calculate math expression from a string using eval

You can use eval. For example:
eval('echo 5*3;')
will echo the number 15.

Simple, short and save solution:
$a = 5;
$b = 3
$o = "*";
$simplecalc = function($a,$b,$op) {
switch($op):
case "*":
return $a*$b;
case "+":
return $a+$b;
case "-":
return $a-$b;
case "/";
return $a/$b;
default:
return false;
endswitch;
};
$result = $simplecalc($a,$b,$o);

I believe this is what you are looking for.
$a = 5;
$b = 3;
$o = "*";
$result = eval( "echo $a$o$b;" );
echo $result;
Please note that using eval() is very dangerous, because it allows execution of arbitrary PHP code.

Related

How to run a comparison within a string in 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.

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.

PHP - Check if a string contains any of the chars in another string

How can I check if a string contains any of the chars in another string with PHP?
$a = "asd";
$b = "ds";
if (if_first_string_contains_any_of_the_chars_in_second_string($a, $b)) {
echo "Yep!";
}
So in this case, it should echo, since ASD contains both a D and an S.
I want to do this without regexes.
You can do it using
$a = "asd";
$b = "ds";
if (strpbrk($a, $b) !== FALSE)
echo 'Found it';
else
echo "nope!";
For more info check : http://php.net/manual/en/function.strpbrk.php
Second parameter is case sensitive.
+1 #hardik solanki. Also, you can use similar_text ( count/percent of matching chars in both strings).
$a = "asd";
$b = "ds";
if (similar_text($a, $b)) {
echo "Yep!";
}
Note: function is case sensitive.
you can use str_split function here, then just have a look at the given links:
this might help you,
http://www.w3schools.com/php/showphp.asp?filename=demo_func_string_str_split
http://www.w3schools.com/php/func_array_intersect.asp
try to use strpos
. Hope it helpful

Assignment operator as a variable in php

I am trying to use an operator as a variable.
$num1 = 33;
$num2 = 44;
$operator = "+";
$answer = ($num1.$operator.$num2);
It prints "33+44" instead of 77.
Or,
$operators = array(
"plus"=>"+",
"minus"=>"-",
"times"=>"*",
"div"=>"/"
);
I want to be able to use as: $answer = $num1.$operators["plus"].$num2;
How can I achieve this without using "if" statement?.
$answer = ($operator == "+") ? $num1 + $num2 : 0;
$num1 = 33;
$num2 = 44;
$operator = "+";
eval("\$result = $num1 $operator $num2;");
echo $result;
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.
On the user-land
Think about things that you're trying to achieve. Why don't create fixed-code closures? You may easily do it with:
$operators = array(
"plus"=>function($x, $y)
{
return $x+$y;
},
"minus"=>function($x, $y)
{
return $x-$y;
},
"times"=>function($x, $y)
{
return $x*$y;
},
"div"=>function($x, $y)
{
return $x/$y;
}
);
//in PHP 5.5:
$result = $operators['plus']($num1, $num2);
//in PHP<5.5:
//$result = call_user_func_array($operators['plus'], [$num1, $num2])
Now you have two things: first, it's still dynamic code - and you may use it in expressions. Next, you're safe in terms of code evaluation - because you've defined the code by yourself. This approach also has advantage - you may define desired behavior as you wish. For instance, raise an exception for "div" operator if second operand is zero.
"Easy" way
I'll notice this only to explain why this isn't a right way. You may use eval(). It's like:
eval('$result='.$num1.$operators['plus'].$num2.';');
And then your result would be stored in $result variable. It is about "easy" way, but not "right" way. The problem is - it is unsafe. Just think about it - you're executing some code, which is dynamic. If your code has nothing to do with user input, it may be applicable - in case, if you're checking your operands and operator before. But I still recommend to think twice before applying it.
If evaluation still needed
Then I recommend to look to some existing implementations. Here are some links:
Safe math calculation instead of eval()
Existing math evaluation repo (github)
You can try to use BC Math functions. This example works with php 5.5:
$num1 = 33;
$num2 = 44;
$operator = '+';
$funcs = array(
'+' => 'bcadd',
'-' => 'bcsub',
'/' => 'bcdiv',
'*' => 'bcmul',
);
$answer = $funcs[$operator]($num1, $num2); // 77
I question why you want to pass the arithmetic operator as a string in the first place, but here's a way to do it without using an if statement:
function fancy_math($num1 = 0, $num2 = 0, $operator = '+')
{
switch ($operator) {
case 'minus':
case '-':
return $num1 - $num2;
break;
case 'times':
case '*':
return $num1 * $num2;
break;
case 'div':
case '/':
return ($num2 !== 0) ? $num1 / $num2 : 'Error: divide by zero';
break;
default:
return $num1 + $num2;
break;
}
}
And then call it like this:
$answer = fancy_math($num1, $num2, $operator);
Note you can pass 'minus' or '-' (etc) as the $operator as it will accept both. If you don't pass an $operator it will assume 'plus' or '+' automatically.

Simplify an If/Else statement with null checks

I'd like a way to simplify an if/else statement that concatenates two values together, but also checks for null values before using the variables.
For example:
if (isset($A,$B)) {
$C = $A . $B;
}
elseif(isset($A)) {
$C = $A;
}
elseif(isset($B)) {
$C = $B;
}
Before concatenating $A with $B I need to make sure neither are NULL. If they both contain a value, then I want to assign the concatenation to the variable $C. If either value is null, then I want just one value assigned to $C.
The above works fine when I only have two variables, but what if a third variable $D were added and I needed to concatenate into $C and still check for nulls. Then I would need to check first for ABD, then AB, then BD, then A, then B, then D. It will get really unruly.
So how can I simplify the code and allow for more variables to be added in the future if necessary?
How about the following:
<?php
$a=NULL;
$b="hello ";
$c=NULL;
$d="world\n";
$all = implode(array($a,$b,$c,$d));
echo $all;
?>
This prints
hello world
without any errors. It is an implementation of the comment that #wor10ck made - but he didn't seem to follow up with a full answer / example and I thought his suggestion was worth fleshing out.
EDIT for people who don't read comments - #Keven ended up using
$result = implode(array_filter($array));
which is a nice robust way to remove the NULL elements in the array.
$C = (isset($A) ? $A : '') . (isset($B) ? $B : '') . (isset($D) ? $D : '');
You might find this usefull
$C = "";
$C .= (isset($A) ? $A : "").(isset($B) ? $B : "");
The question mark operator returns the left part before the : symbol if the statement is true, and right if false. Hoever i think that nesting statements in if block is more optimised.
<?php
// I assume $res is the variable containing the result of the concatenations
$res = '';
if(isset($a))
$res .= $a;
if(isset($b))
$res .= $b;
if(isset($c))
$res .= $c;
// ...
$A = 'a';
$B = 'b';
$C = '';
$C .= isset($A) ? $A : '';
$C .= isset($B) ? $B : '';
$C .= isset($D) ? $D : '';
echo $C;

Categories