【发布时间】: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
所以我有如下内容:
$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
不,该语法不可用。最好的方法是 eval(),不建议这样做,特别是如果 $e 来自用户输入(即表单),或者每个运算符作为 case 的 switch 语句
switch($e)
{
case "||":
if($a>$b || $c>$d)
echo 'yes';
break;
}
【讨论】:
这是不可能的,但您可以使用函数。当然,您必须自己定义它们。使用 PHP 5.3 的闭包会相当简单:
$or = function($x, $y)
{
return $x || $y;
};
if ($or($a > $b, $c > $d))
{
echo 'yes';
};
【讨论】:
这是一个添加一些模糊和未定义的“附加标准”以缩小产品列表的功能。
/**
* 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;
}
}
【讨论】:
请使用此代码更改字符串运算符以转换为实际格式
<?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";
}
【讨论】:
【讨论】:
只是为了使列表完整,这是我使用的功能。它拥有所有的运营商。最好不要使用 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
}
【讨论】:
不,没有办法在 PHP AFAIK 中重新定义运算符(或使用变量运算符)。
少用eval(),我能想到的最接近的就是创建一个函数:
function my_operator ($cond1, $cond2)
{
if ( .... )
return ($cond1 || $cond2);
else
return ($cond1 && $cond2);
}
if (my_operator(($a > $b), ($c > $d)))
....
【讨论】:
不,这是不可能的。
【讨论】:
您可以使用 eval,但如果您不小心的话,您很容易最终将您的网站暴露在各种代码注入攻击之下。
更安全的解决方案是将提议的运算符与预定义的白名单进行匹配,然后如果对运算符进行硬编码,则调用相应的位。
C.
【讨论】:
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 当然很有趣。但在脚本语言的上下文中略有误导,无论如何它是一个内置功能。
【讨论】: