【问题标题】:Evaluate concatonated operator with numbers用数字评估连接运算符
【发布时间】:2018-11-23 16:01:28
【问题描述】:

我正在为一小段不想评估自己的代码苦苦挣扎:

$t = 5;
$s = "<=";
$r = 6;

var_dump($t.$s.$r);

这里的 var_dump 返回 "5&lt;=6" 这是有道理的,但我只想告诉我 5 是否低于或等于 6 的布尔值

我想知道除了使用eval() 或通过所有可能的运算符进行切换之外,是否还有其他方法可以获取此布尔值

提前致谢。

【问题讨论】:

  • 输入将达到什么复杂度?只是算术吗?总是 2 个操作数?
  • 是的,总是一个数字,一个运算符(=,>),另一个数字
  • 您可能想研究Symfony's ExpressionLanguage component 之类的东西,它允许评估任意计算,但也可以处理清理/验证/等。
  • 如果它总是x op y,那么一个简单的switch 是要做的事情,其他方法将是严重的矫枉过正。

标签: php operators eval concat


【解决方案1】:

如果您想要一个安全灵活的解决方案,这允许您定义一个方法,该方法根据与数组中键匹配的运算符执行,它仅适用于两个操作数,但示例中的最后一个操作数#只需将第一个值乘以 4 并返回值...

$operators = [ "<=" => function ($a, $b) { return $a <= $b;},
    "<" => function ($a, $b) { return $a < $b;},
    ">=" => function ($a, $b) { return $a >= $b;},
    ">" => function ($a, $b) { return $a > $b;},
    "#" => function ($a) { return $a * 4; }];

$t = 5;
$s = "<=";
$r = 6;
var_dump($operators[$s]($t,$r));

$s = "<";
var_dump($operators[$s]($t,$r));

$s = ">=";
var_dump($operators[$s]($t,$r));

$s = ">";
var_dump($operators[$s]($t,$r));

$s = "#";
var_dump($operators[$s]($t,$r));

给...

/home/nigel/workspace2/Test/t1.php:14:
bool(true)
/home/nigel/workspace2/Test/t1.php:17:
bool(true)
/home/nigel/workspace2/Test/t1.php:20:
bool(false)
/home/nigel/workspace2/Test/t1.php:23:
bool(false)
/home/nigel/workspace2/Test/t1.php:26:
int(20)

它有点复杂,但可扩展且安全。

【讨论】:

  • 它也与使用 switch 一样高效和灵活 - 只需将不同的函数存储在数组中,而不是硬编码在 case 语句中。
  • 它是否比 switch 更好是值得商榷的,因为 switch 更直接,但像许多解决方案一样,它有时取决于您想要实现的语义
  • 同意!我不太明白为什么 OP 排除了 switch,因为它是解决手头问题的最直接的方法(除了 eval)——但他还是这么做了。
【解决方案2】:

虽然使用这样的代码通常不是一个好主意(评估存储为纯文本的代码),但有一个函数可以解决这个问题:eval()

eval() 做了您期望 PHP 自然做的事情:评估存储在字符串中的有效代码。

eval("var_dump(".$t.$s.$r.");"); 可以完成这项工作 - 但是,由于这些变量中的任何代码都会毫无疑问地执行,因此可能存在安全风险,或者至少会引入一些难以调试的错误。 (需要额外的引用和; 才能使 eval 中的代码实际上是有效的 PHP 代码)

【讨论】:

  • 我知道 eval() 可以完成这项工作,但关于 eval 有多不安全,我想知道是否有其他方法来计算这个表达式
  • 问题说除了使用 eval 或 switch。
  • 哎呀,我错过了那部分。那么,没有其他方法不具有与使用 eval 相同的缺点或与使用 switch 相同的效率。
猜你喜欢
  • 2011-08-15
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 2019-01-12
  • 2018-05-23
  • 2016-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多