PHP-实现字符串表达式计算
什么是字符串表达式?即,将我们常见的表达式文本写到了字符串中,如:"$age >= 20",$age 的值是动态的整型变量。什么是字符串表达式计算?即,我们需要一段程序来执行动态的表达式,如给定一个含表达式的字符串变量并计算其结果,而表达式字符串是动态的,比如为客户A执行的表达式是 $orderCount >= 10,而为客户B执行的表达式是 $orderTotal >= 1000。 场景在哪儿?同一份程序具有完全通用性,但差异就其中一个表达式而已,那么我们需要将其抽象出来,让表达式变成动态的、可配置的、或可生成的。 方案一:eval 函数eval 函数可能是我们第一个想到的方案,也是最简单直接的方案。我们来试验下: $a = 10;var_dump(eval('return $a > 5;'));// 输出:// bool(true)嗯~完全能满足我们的需求,因为 eval 函数执行的 PHP 表达式,只要字符串内表达式符合 PHP 语法就行。 但需注意的是,eval 函数可执行任意 PHP 代码,也就意味着权限大、风险高、不安全。如果你的字符串表达式来自于外部输入,那务必注意了请自行做好安全检查和过滤,并考虑风险。当然,执行的是外部输入表达式,非常不建议使用此函数。 方案二:include 临时文件如何实现?将字符串表达式写入一个临时文件,然后 include 这个临时文件,执行完成后再删除这个临时文件。 方案依然很简单。需要考虑的有: 临时文件会很多,一个请求就有很多个,文件的过期和删除务必考虑在内文件的读写,也就牵扯到了磁盘 IO,那性能必定受到严重影响那这个方案我们还采用吗? 方案三:assert 断言其实 assert 做不到字符串表达式的计算,但提出来也算个猜想,因为能实现 PHP 表达式是否合法的校验。 下例演示了如何验证某个字符串表达式是否为合法的 PHP 表达式: try { assert('a +== 1');} catch (Throwable $e) { echo $e->getMessage(), "\n";}运行结果: Failure evaluating code: a +== 1可依然面临一个问题,那就是安全性,因为与 eval 一样能执行任意代码。所以,从 PHP 7.2 开始就不可以再执行字符串类型的表达式了。关于 PHP assert 断言,可参考 你所不知的 PHP 断言(assert) ...