PHP 中的动态比较运算符

Posted

技术标签:

【中文标题】PHP 中的动态比较运算符【英文标题】:Dynamic Comparison Operators in PHP 【发布时间】: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,你可以。它可以是一个非常强大的模式。 【参考方案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 变量然后对其进行求值,直接在此处进行求值不是更容易吗?

【讨论】:

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

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

【讨论】:

以上是关于PHP 中的动态比较运算符的主要内容,如果未能解决你的问题,请参考以下文章

PHP 中的 !== 比较运算符是啥意思?

PHP运算符

PHP运算符

比较运算符

PHP <=> 太空船运算符(组合比较符)

php中运用三元运算符比较三个数大小并从大到小输出