简体   繁体   English

PHP 中的动态比较运算符

[英]Dynamic Comparison Operators in PHP

Is it possible, in any way, to pass comparison operators as variables to a function?是否有可能以任何方式将比较运算符作为变量传递给 function? I am looking at producing some convenience functions, for example (and I know this won't work):我正在考虑产生一些便利功能,例如(我知道这行不通):

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

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

Thanks in advance.提前致谢。

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

How about this one? 这个怎么样?

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

Test: 测试:

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

How about a small class: 小班上怎么样:

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

The bigger problem is that this function is pretty pointless. 更大的问题是这个功能毫无意义。 Let's replace that with a real (hypothetically working) example: 让我们用一个真实的(假设工作的)例子取而代之:

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

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

In this example $foo is not set. 在此示例中,未设置$foo You'll get an error because you're trying to pass a non-existent variable ( $foo ) to a function ( isAnd ). 你会得到一个错误,因为你试图将一个不存在的变量( $foo )传递给一个函数( isAnd )。 So, you will need to test $foo for isset before calling isAnd : 因此, 调用isAnd 之前 ,您需要为isset测试$foo

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

So, any variable that ever enters the isAnd function is definitely set. 因此,任何进入isAnd函数的变量都是明确设置的。 You don't need to test for it inside the function. 您不需要在函数内测试它。 So the whole exercise is pretty pointless. 所以整个练习都是毫无意义的。

What may be confusing is that isset() and empty() don't have this limitation, ie you can pass a non-existent variable to them without error. 可能令人困惑的是, isset()empty()没有此限制,即您可以将不存在的变量传递给它们而不会出现错误。 The thing is though, these are not normal functions, they're special language constructs (that happen to look like functions; blame PHP). 但事情是,这些不是正常的函数,它们是特殊的语言结构(恰好看起来像函数;怪PHP)。 Unfortunately you can not make these kinds of constructs, parameters for your functions always need to exist. 遗憾的是, 无法制作这些类型的构造,您的函数的参数始终需要存在。

You should just get used to writing isset($foo) && $foo === 1 . 你应该习惯于编写isset($foo) && $foo === 1 With properly structured code, you can reduce this to a minimum by always declaring all variables you're going to use, which is good practice anyway. 使用结构合理的代码,您可以通过始终声明要使用的所有变量将此值降至最低,这无论如何都是很好的做法。

For the dynamic operator... you'll need some form of if ... else somewhere to decide which operator to use anyway. 对于动态运算符......你需要某种形式的if ... else来决定使用哪个运算符。 Instead of setting the operator variable and then evaluating it, isn't it easier to do the evaluation right there? 而不是设置操作员变量然后评估它,是否更容易在那里进行评估?

If you absolutely insist you can use eval. 如果你绝对坚持你可以使用eval。

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

But I wouldn't recommend it. 但我不推荐它。

The top answer recommends a small class, but I like a trait. 最佳答案推荐一个小班,但我喜欢一个特质。

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

}

As Michael Krelin suggests you could use eval - but that potentially enables a lot of code injection attacks. 正如Michael Krelin建议您可以使用eval - 但这可能会导致许多代码注入攻击。

You can't substitute a variable for an operator - but you can substitute a variable for a function: 您不能将变量替换为运算符 - 但您可以将变量替换为函数:

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. C。

Here is a simple solution which should work for almost all the operators 这是一个简单的解决方案,几乎适用于所有运营商

Eg. 例如。

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

Output: 输出:

15

Another example with comparison operator: 另一个比较运算符示例:

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

Output: 输出:

false

Hope this helps. 希望这可以帮助。

As far as I know it is not possible and since there is no reference about callback on operators in PHP documentation, http://www.php.net/manual/en/language.operators.php 据我所知,这是不可能的,因为在PHP文档中没有关于运算符回调的参考, http://www.php.net/manual/en/language.operators.php

instead of using eval, I would redefine each operators in global functions and use php callbacks How do I implement a callback in PHP? 而不是使用eval,我将重新定义全局函数中的每个运算符并使用php回调如何在PHP中实现回调?

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

No, it's impossible. 不,这是不可能的。 You can use conditional operators instead, but it will be much,much better if you redesign your application to make such a dynamic comparison unnecessary. 您可以使用条件运算符,但如果重新设计应用程序以进行此类动态比较,则会更好,更好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM