【问题标题】:Using a variable as an operator使用变量作为运算符
【发布时间】:2011-01-16 19:48:14
【问题描述】:

所以我有如下内容:

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

然后我进行类似的比较

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

一切正常。是否可以使用变量代替运算符? 比如:

$e = ||;

然后我可以用作

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

【问题讨论】:

    标签: php


    【解决方案1】:

    不,该语法不可用。最好的方法是 eval(),不建议这样做,特别是如果 $e 来自用户输入(即表单),或者每个运算符作为 case 的 switch 语句

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

    【讨论】:

      【解决方案2】:

      这是不可能的,但您可以使用函数。当然,您必须自己定义它们。使用 PHP 5.3 的闭包会相当简单:

      $or = function($x, $y)
      {
          return $x || $y;
      };
      
      if ($or($a > $b, $c > $d))
      {
          echo 'yes';
      };
      

      【讨论】:

        【解决方案3】:

        这是一个添加一些模糊和未定义的“附加标准”以缩小产品列表的功能。

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

        这是我的使用方法:

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

        【讨论】:

          【解决方案4】:

          请使用此代码更改字符串运算符以转换为实际格式

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

          【讨论】:

            【解决方案5】:
            公共函数 checkOperator($value1, $operator, $value2) { 开关($操作员){ case '%': // 百分比 返回 $value1 % $value2; case '+': // 求和 返回 $value1 + $value2; case '-': // 减法 返回 $value1 - $value2; case '*': // 乘法 返回 $value1 * $value2; case '/': // 被分割的 返回 $value1 / $value2; case '': // 大于 返回 $value1 > $value2; case '>=': // 大于等于 返回 $value1 >= $value2; case '==': // 相等 返回 $value1 == $value2; case '===': // 相同 返回 $value1 === $value2; case '!==': // 不相同 返回 $value1 !== $value2; case '!=': // 不相等 case '': // 不相等 返回 $value1 != $value2; case '||': // 或者 case 'or': // 或 返回 $value1 || $价值2; case '&&': // 和 case 'and': // 和 返回 $value1 && $value2; case 'xor': // 或 返回 $value1 xor $value2; 默认: 返回假; } }

            【讨论】:

            • 你应该给出你在回答中写的代码的细节和解释。
            【解决方案6】:

            只是为了使列表完整,这是我使用的功能。它拥有所有的运营商。最好不要使用 eval()。这会更快更安全。

            /* -------------------------------------------------------------------------
             * 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
            
            

            叫它:

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

            【讨论】:

              【解决方案7】:

              不,没有办法在 PHP AFAIK 中重新定义运算符(或使用变量运算符)。

              少用eval(),我能想到的最接近的就是创建一个函数:

              function my_operator ($cond1, $cond2)
               {
                 if ( ....  ) 
                   return ($cond1 || $cond2);
                 else
                   return ($cond1 && $cond2);
              
               }
              
              if (my_operator(($a > $b), ($c > $d)))
               ....
              

              【讨论】:

                【解决方案8】:

                不,这是不可能的。

                【讨论】:

                  【解决方案9】:

                  您可以使用 eval,但如果您不小心的话,您很容易最终将您的网站暴露在各种代码注入攻击之下。

                  更安全的解决方案是将提议的运算符与预定义的白名单进行匹配,然后如果对运算符进行硬编码,则调用相应的位。

                  C.

                  【讨论】:

                    【解决方案10】:

                    eval 在这种情况下使用通常是完全合法的,如果您使用任意用户输入或可以白名单简单数学表达式:

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

                    编写自己的math parser 当然很有趣。但在脚本语言的上下文中略有误导,无论如何它是一个内置功能。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-04-21
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-04-06
                      • 2011-08-15
                      • 2014-10-11
                      • 1970-01-01
                      相关资源
                      最近更新 更多