【问题标题】:Dynamic Comparison Operators in PHPPHP 中的动态比较运算符
【发布时间】:2011-02-24 12:57:57
【问题描述】:

是否有可能以任何方式将比较运算符作为变量传递给函数?例如,我正在考虑生成一些便利功能(我知道这行不通):

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

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

提前致谢。

【问题讨论】:

  • 这样的功能有什么意义?函数调用比操作本身要长得多,我想不出有什么有用的。
  • 如果你使用Scheme,你可以。它可以是一个非常强大的模式。

标签: php variables operators


【解决方案1】:

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

【讨论】:

  • 天才。 +1 这是一个非常有创意的解决方案,非常适合数字比较。
  • 这里是例子,if (version_compare(5.9, 6,'<=')) echo TRUE; // returns 1
  • 我实际上是在创建自己的版本比较功能,因为我不知道 PHP 有这个功能,太棒了!
  • 请注意,这不适用于任何任意字符串,仅适用于数字字符串。
【解决方案2】:

这个怎么样?

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";
}

【讨论】:

  • 您应该在测试中包含输入/输出。
  • 最佳答案。谢谢!
【解决方案3】:

一个小班怎么样:

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;
  }
}

【讨论】:

  • 我什至没有考虑过上课,也许早上太早了?谢谢。
  • 为什么需要一个类?
  • 在 5.3 之前这是最好的选择,使用命名空间和真正的回调其他好的解决方案是可能的。但类可能是最简单的。
  • 理解您的问题需要一些时间。你是对的,类不是必需的,但它是 PHP 中的常见做法。
  • 很有目的的做个对比课!解决了我的问题!这个问题类似于我的问题。非常便利 ! +1
【解决方案4】:

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

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;
}

}

【讨论】:

    【解决方案5】:

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

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

    在此示例中,$foo 未设置。你会得到一个错误,因为你试图将一个不存在的变量 ($foo) 传递给一个函数 (isAnd)。因此,您需要在调用isAnd 之前测试$fooisset

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

    因此,任何进入isAnd 函数的变量都肯定被设置。您无需在函数内部对其进行测试。所以整个练习是毫无意义的。

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

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

    对于动态运算符...您需要某种形式的if ... else 来决定无论如何要使用哪个运算符。与其设置 operator 变量然后对其进行求值,直接在此处进行求值不是更容易吗?

    【讨论】:

    【解决方案6】:

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

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

    但我不会推荐它。

    【讨论】:

    • +1 - 但对您为什么不推荐它的一些解释可能对读者有价值
    【解决方案7】:

    正如 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)) {
       ....
    

    C.

    【讨论】:

      【解决方案8】:

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

      例如。

      $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
      

      希望这会有所帮助。

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:
          $a = 4;
          eval('$condition=($a == 4)?true:false;'); 
          if($condition){ echo "Yes"; }else{ echo "No"; }
          

          【讨论】:

          • Manoj Kumar,您想通过补充一些解释来改进您的问题吗?这将提高您获得支持的机会,同时有助于消除 StackOverflow 只是一种无偿代码编写服务的误解。
          • 在解释中,如果您能解释与 Akshay Khale 提供的答案的区别,那将特别有帮助。除了 is 一个解释和一个更不言自明和令人信服的示例之外,我没有看到任何功能差异,它比在您的代码中更明显地展示了运算符与表达式的分离。
          【解决方案11】:

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

          【讨论】:

            猜你喜欢
            • 2021-12-04
            • 1970-01-01
            • 1970-01-01
            • 2013-09-16
            • 2011-03-07
            • 2012-10-05
            • 1970-01-01
            相关资源
            最近更新 更多