Page 1 of 1

Turn string into operator?

Posted: Sun Jul 05, 2009 11:53 am
by 37seconds
I am trying to write a function that will evaluate 2 values, but the operator can be dynamic.

For example:

Code: Select all

 
function evaluate($value1, $operator, $value2)
{
  if ($value1 { $operator } $value2)
  {
    return true;
  }
  else
  {
    return false;
  }
}
 
$test = evaluate(3, ">", 1);
 
Is there any way this can be done?

Thanks in advance!

Re: Turn string into operator?

Posted: Sun Jul 05, 2009 4:35 pm
by requinix
Since you're going through the effort to filter out bad operators, might as well fix the numbers going in.

Code: Select all

<?php
$a = 32;
$b = 42;
$operator = '>';
 
$conditional_operators = array('==', '===', '!=', '!==', '<>', '<', '>', '<=', '>=');
$result = null;
if (in_array($operator, $conditional_operators) && is_numeric($a) && is_numeric($b)) {
    eval("\$result = (\$a $operator \$b);");
}
var_dump($result); // Should be true, false, or null
?>

Re: Turn string into operator?

Posted: Mon Jul 06, 2009 12:01 pm
by Mark Baker
Avoid eval() like the plague. Bad habits (even when the data is safe) lead to bad habits when it is unsafe.

Code: Select all

 
function evaluate($value1, $operator, $value2)
{
   $result = false;
   switch($operator) {
      case '=' :
      case '==' :
         $result = ($value1 == $value2);
         break;
      case '!=' :
         $result = ($value1 != $value2);
         break;
      case '>' :
         $result = ($value1 > $value2);
         break;
      case '>=' :
         $result = ($value1 >= $value2);
         break;
      ...
   }
   return $result;
}
 
$test = evaluate(3, ">", 1);
 

Re: Turn string into operator?

Posted: Mon Jul 06, 2009 12:34 pm
by requinix
Mark Baker wrote:Avoid eval() like the plague. Bad habits (even when the data is safe) lead to bad habits when it is unsafe.
For most people I'd agree, but there are some of us who know what we're doing. Blindly saying things like "eval is bad" - I used to myself - isn't fair.

Re: Turn string into operator?

Posted: Tue Jul 07, 2009 4:04 am
by Mark Baker
tasairis wrote:For most people I'd agree, but there are some of us who know what we're doing. Blindly saying things like "eval is bad" - I used to myself - isn't fair.
Even when there are circumstances where the use of eval() might not be considered bad, there are generally better alternatives (or at least alternatives), e.g. perhaps a lambda function (nearly as "dirty", though it's not particularly efficient).

Code: Select all

 
$conditional_operators = array('==', '===', '!=', '!==', '<>', '<', '>', '<=', '>=');
$result = null;
if (in_array($operator, $conditional_operators) && is_numeric($a) && is_numeric($b)) {
   $comparator = create_function('$a,$b','return ($a '.$operator.' $b);');
   return $comparator($a,$b);
}
 
In this instance, my switch statement is significantly faster than eval.
Measured over 10000 calls

Code: Select all

 
Call time for Case Evaluation was 0.0352 seconds
Call time for Eval Evaluation was 0.2457 seconds
Call time for Lambda Function Evaluation was 0.7116 seconds
 

Re: Turn string into operator?

Posted: Tue Jul 07, 2009 4:40 am
by onion2k
I'd agree that, in this case, where there are a finite number of cases using a switch is the better option. The point of eval() is that it's essential where you're doing meta-programming - writing code that writes code. If you're not doing that you shouldn't be using eval(). You definitely shouldn't ever use it as a short cut.