Turn string into operator?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
37seconds
Forum Newbie
Posts: 1
Joined: Sun Jul 05, 2009 11:43 am

Turn string into operator?

Post 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!
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Turn string into operator?

Post 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
?>
Mark Baker
Forum Regular
Posts: 710
Joined: Thu Oct 30, 2008 6:24 pm

Re: Turn string into operator?

Post 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);
 
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Turn string into operator?

Post 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.
Mark Baker
Forum Regular
Posts: 710
Joined: Thu Oct 30, 2008 6:24 pm

Re: Turn string into operator?

Post 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
 
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: Turn string into operator?

Post 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.
Post Reply