开发者

Using a variable as an operator

开发者 https://www.devze.com 2022-12-20 07:52 出处:网络
So I h开发者_开发百科ave something like the following: $a = 3; $b = 4; $c = 5; $d = 6; and I run a comparison like

So I h开发者_开发百科ave something like the following:

$a = 3;
$b = 4;
$c = 5;
$d = 6;

and I run a comparison like

if($a>$b || $c>$d) { echo 'yes'; };

That all works just fine. Is it possible to use a variable in place of the operator? Something like:

$e = ||;

Which I could then use as

if($a>$b $e $c>$d) { echo 'yes'; };


No, that syntax isn't available. The best you could do would be an eval(), which would not be recommended, especially if the $e came from user input (ie, a form), or a switch statement with each operator as a case

switch($e)
{
    case "||":
        if($a>$b || $c>$d)
            echo 'yes';
    break;
}


It's not possible, but you could use a function instead. Of course, you'd have to define them yourself. This would be fairly simple using PHP 5.3's closures:

$or = function($x, $y)
{
    return $x || $y;
};

if ($or($a > $b, $c > $d))
{
    echo 'yes';
};


Here's a function to add some vague and undefined "additional criteria" for narrowing down a list of products.

/**
 * Criteria checker
 *
 * @param string $value1 - the value to be compared
 * @param string $operator - the operator
 * @param string $value2 - the value to test against
 * @return boolean - criteria met/not met
 */
protected function criteriaMet($value1, $operator, $value2)
{
    switch ($operator) {
        case '<':
            return $value1 < $value2;
        case '<=':
            return $value1 <= $value2;
        case '>':
            return $value1 > $value2;
        case '>=':
            return $value1 >= $value2;
        case '==':
            return $value1 == $value2;
        case '!=':
            return $value1 != $value2;
        default:
            return false;
    }
}

Here's how I used it:

// Decode the criteria
$criteria = json_decode($addl_criteria);

// Check input against criteria
foreach ($criteria as $item) {
    // Criteria fails
    if (!criteriaMet($input[$item->key)], $item->operator, $item->value)) {
        return false;
    }
}


Please use this code for change the string operator to convert in actual format

 <?php

  $a = 3;
  $b = 4;
  $c = 5;
  $d = 6;
  $e='&&';
  $lt='<';
  $gt='>';

  if(eval('return '.$a.$lt.$b.$e.$c.$gt.$d.';')){
    echo "yes";
  }else{
    echo "No";
  }


 public function checkOperator($value1, $operator, $value2)
    {
        switch ($operator) {
            case '%': // Percentage
                return $value1 % $value2;
            case '+': // Sum
                return $value1 + $value2;
            case '-': // subtraction
                return $value1 - $value2;
            case '*': // Multiplication
                return $value1 * $value2;
            case '/': // Divided
                return $value1 / $value2;
            case '': // Greater than
                return $value1 > $value2;
            case '>=': // Greater than or equal to
                return $value1 >= $value2;
            case '==': // Equal
                return $value1 == $value2;
            case '===': // Identical
                return $value1 === $value2;
            case '!==': // Not Identical
                return $value1 !== $value2;
            case '!=': // Not equal
            case '': // Not equal
                return $value1 != $value2;
            case '||': // Or
            case 'or': // Or
                return $value1 || $value2;
            case '&&': // And
            case 'and': // And
                return $value1 && $value2;
            case 'xor': // Or
                return $value1 xor $value2;
            default:
                return false;
        }
    }


Just to make the list complete this is the function I use. It has all the operators. Its better not to use eval(). This will be much quicker and safer.

/* -------------------------------------------------------------------------
 * checks 2 values with operator
 * you can use logical operators als well
 * returns FALSE or TRUE
 */
function checkOperator($value1, $operator, $value2) {
    switch ($operator) {
        case '<': // Less than
            return $value1 < $value2;
        case '<=': // Less than or equal to
            return $value1 <= $value2;
        case '>': // Greater than
            return $value1 > $value2;
        case '>=': // Greater than or equal to
            return $value1 >= $value2;
        case '==': // Equal
            return $value1 == $value2;
        case '===': // Identical
            return $value1 === $value2;
        case '!==': // Not Identical
            return $value1 !== $value2;
        case '!=': // Not equal
        case '<>': // Not equal
            return $value1 != $value2;
        case '||': // Or
        case 'or': // Or
           return $value1 || $value2;
        case '&&': // And
        case 'and': // And
           return $value1 && $value2;
        case 'xor': // Or
           return $value1 xor $value2;  
        default:
            return FALSE;
    } // end switch

To call it:


$value1 = 12;
$operator = '>';
$value2 = 13;
if (checkOperator($value1, $operator, $value2)) {
    ... its true
} else {
    ... its not true
}


eval is often perfectly legitimate to use in such cases, if you don't use arbitrary user input or can whitelist simple math expressions:

 $expr = "$var1 $op $var2";
 $rx_math = '/^
      \d+(\.\d+)? \s*              # numeric
      ([-+\/*<>^%]|>=|<=|==)       # operator
      \s* \d+(\.\d+)?              # numeric
 $/x';
 if (preg_match($rx_math, $expr)) {
      eval("\$result = $expr;");
 }

Writing your own math parser is fun of course. But slightly misguided in the context of scripting languages, where it's a built-in feature anyway.


Nope, there is no way to re-define operators (or use variable operators) in PHP AFAIK.

Short of using eval(), the closest I can think of is creating a function:

function my_operator ($cond1, $cond2)
 {
   if ( ....  ) 
     return ($cond1 || $cond2);
   else
     return ($cond1 && $cond2);

 }

if (my_operator(($a > $b), ($c > $d)))
 ....


No, it is not possible.


You could use eval, but that you could easily end up exposing your site to all sorts of code injection attacks if you're not very careful.

A safer solution would be to match the proposed operator against a predefined white list and then call a corresponding bit if code with the operator hard - coded.

C.

0

精彩评论

暂无评论...
验证码 换一张
取 消