PHP中的动态比较运算符

时间:2010-05-27 07:22:24

标签: php variables operators

是否有可能将比较运算符作为变量传递给函数?我正在寻找一些便利功能,例如(我知道这不起作用):

function isAnd($var, $value, $operator = '==')
{
    if(isset($var) && $var $operator $value)
        return true;
}

if(isAnd(1, 1, '===')) echo 'worked';

提前致谢。

11 个答案:

答案 0 :(得分:29)

您也可以使用version_compare()函数,因为您可以传递将用作比较的运算符作为第三个参数。

答案 1 :(得分:17)

这个怎么样?

function num_cond ($var1, $op, $var2) {

    switch ($op) {
        case "=":  return $var1 == $var2;
        case "!=": return $var1 != $var2;
        case ">=": return $var1 >= $var2;
        case "<=": return $var1 <= $var2;
        case ">":  return $var1 >  $var2;
        case "<":  return $var1 <  $var2;
    default:       return true;
    }   
}

测试:

$ops = array( "=", "!=", ">=", "<=", ">", "<" );
$v1 = 1; $v2 = 5;

foreach ($ops as $op) {
    if (num_cond($v1, $op, $v2)) echo "True  ($v1 $op $v2)\n"; else echo "False ($v1 $op $v2)\n";
}

答案 2 :(得分:10)

小班上怎么样:

class compare
{
  function is($op1,$op2,$c)
  {
     $meth = array('===' => 'type_equal', '<' => 'less_than');
     if($method = $meth[$c]) {
        return $this->$method($op1,$op2);
     }
     return null; // or throw excp.
  }
  function type_equal($op1,$op2)
  {
      return $op1 === $op2;
  }
  function less_than($op1,$op2)
  {
      return $op1 < $op2;
  }
}

答案 3 :(得分:3)

更大的问题是这个功能毫无意义。让我们用一个真实的(假设工作的)例子代替它:

function isAnd($var, $value, $operator = '==') {
    return isset($var) && $var $operator $value;
}

isAnd($foo, 1, '===');

在此示例中未设置$foo。您将收到错误,因为您尝试将不存在的变量($foo)传递给函数(isAnd)。因此,在调用$foo之前,您需要对isset 进行isAnd测试:

isset($foo) && isAnd($foo, 1, '===');

因此,任何进入isAnd函数的变量都是明确设置的。您不需要在函数内测试它。所以整个练习都是毫无意义的。

可能令人困惑的是isset()empty()没有此限制,即您可以将不存在的变量传递给它们而不会出现错误。但事情是,这些不是正常的函数,它们是特殊的语言结构(恰好看起来像函数;怪PHP)。不幸的是无法制作这些类型的构造,因此总是需要存在函数的参数。

你应该习惯于写isset($foo) && $foo === 1。使用结构合理的代码,您可以通过始终声明您将要使用的所有变量将此值降至最低,这无论如何都是很好的做法。

对于动态运算符......您需要某种形式的if ... else来确定使用哪个运算符。而不是设置运算符变量然后评估它,是不是更容易在那里进行评估?

答案 4 :(得分:2)

如果你绝对坚持,你可以使用eval。

if(isset($var) && eval("return \$var $operator \$value"))
    return true;

但我不推荐它。

答案 5 :(得分:2)

最佳答案推荐一个小班,但我喜欢一个特质。

trait DynamicComparisons{

private $operatorToMethodTranslation = [
    '=='  => 'equal',
    '===' => 'totallyEqual',
    '!='  => 'notEqual',
    '>'   => 'greaterThan',
    '<'   => 'lessThan',
];

protected function is($value_a, $operation, $value_b){

    if($method = $this->operatorToMethodTranslation[$operation]){
        return $this->$method($value_a, $value_b);
    }

    throw new \Exception('Unknown Dynamic Operator.');
}

private function equal($value_a, $value_b){
    return $value_a == $value_b;
}

private function totallyEqual($value_a, $value_b){
    return $value_a === $value_b;
}

private function notEqual($value_a, $value_b){
    return $value_a != $value_b;
}

private function greaterThan($value_a, $value_b){
    return $value_a > $value_b;
}

private function lessThan($value_a, $value_b){
    return $value_a < $value_b;
}

private function greaterThanOrEqual($value_a, $value_b){
    return $value_a >= $value_b;
}

private function lessThanOrEqual($value_a, $value_b){
    return $value_a <= $value_b;
}

}

答案 6 :(得分:1)

正如Michael Krelin建议您可以使用eval - 但这可能会导致大量的代码注入攻击。

您不能将变量替换为运算符 - 但您可以将变量替换为函数:

function is_equal($a, $b) {
  return $a==$b;
} 
function is_same($a, $b) {
  return $a===$b;
}
function is_greater_than($a, $b)
....

$compare='is_equal';
if ($compare($a, $b)) {
   ....

下进行。

答案 7 :(得分:1)

这是一个简单的解决方案,应适用于几乎所有运营商

例如。

$b = 10;
$c = '+';
$p = $a . $c. $b; // Forming a String equation
$p = eval('return '.$p.';'); // Evaluating the Equation
echo $p;

输出:

15

另一个带有比较运算符的示例:

$b = 10;
$c = '==';
$p = $a . $c. $b;
$p = eval('return '.$p.';');
echo $p;

输出:

false

希望这会有所帮助。

答案 8 :(得分:0)

据我所知,这是不可能的,因为在PHP文档中没有关于运算符回调的参考, http://www.php.net/manual/en/language.operators.php

而不是使用eval,我将重新定义全局函数中的每个运算符并使用php回调 How do I implement a callback in PHP?

答案 9 :(得分:0)

$a = 4;
eval('$condition=($a == 4)?true:false;'); 
if($condition){ echo "Yes"; }else{ echo "No"; }

答案 10 :(得分:-3)

不,这是不可能的。 您可以使用条件运算符,但如果您重新设计应用程序以使这种动态比较变得不必要,那么它将更多,更好