
PHP 不支持直接对含运算符的字符串(如 "0 - 10")执行算术运算,需通过解析或求值将其转为数字;但 eval() 存在严重安全风险,推荐优先使用更安全的替代方案。
php 不支持直接对含运算符的字符串(如 "0 - 10")执行算术运算,需通过解析或求值将其转为数字;但 `eval()` 存在严重安全风险,推荐优先使用更安全的替代方案。
在 PHP 中,像 $variable = "0 - 10" 这样的字符串本质上是文本,而非可执行表达式。直接参与算术运算(如 $number + $variable)会导致 PHP 尝试类型转换:"0 - 10" 会被强制转为整数 0(因从左向右解析时遇到非数字字符即停止),最终结果为 50 + 0 = 50,而非预期的 40。
❌ 危险方案:eval()(不推荐)
虽然技术上可行,但 eval() 允许执行任意 PHP 代码,一旦 $variable 来源于用户输入(如表单、URL 参数或数据库),极易引发远程代码执行(RCE)漏洞:
$number = "50";
$variable = "0 - 10";
eval("\$variable = $variable;"); // ⚠️ 极度危险!
$result = $number + $variable;
echo $result; // 输出 40
若 $variable = "system('rm -rf /')",后果不堪设想。因此,生产环境严禁使用 eval() 处理不可信输入。
✅ 推荐方案:安全表达式解析
方案 1:使用 symfony/expression-language(推荐)
安装后可安全解析简单数学表达式:
composer require symfony/expression-language
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$el = new ExpressionLanguage();
$number = 50;
$variable = "0 - 10";
// 安全求值:仅支持数学运算,无函数调用/变量注入风险
try {
$offset = $el->evaluate($variable); // 返回 -10
$result = $number + $offset;
echo $result; // 40
} catch (\Exception $e) {
throw new InvalidArgumentException('无效的数学表达式');
}
方案 2:正则+floatval() 简单校验(适用于固定格式)
若 $variable 始终为 X operator Y 格式(如 "0 - 10"、"100 * 0.5"),可手动解析:
$number = 50;
$variable = "0 - 10";
// 仅允许数字、空格、+ - * / . 和括号
if (!preg_match('/^[\s\d+\-*.\/()]+$/', $variable)) {
throw new InvalidArgumentException('表达式包含非法字符');
}
// 使用内置 eval 替代方案:借助 create_function 已废弃,改用匿名函数 + exec()
// 更稳妥做法:用第三方库或白名单操作符解析
$tokens = preg_split('/([\+\-\*\/])/', trim($variable), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
if (count($tokens) === 3 && in_array($tokens[1], ['+', '-', '*', '/'])) {
$a = floatval($tokens[0]);
$b = floatval($tokens[2]);
$op = $tokens[1];
$offset = match($op) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
'/' => ($b != 0) ? $a / $b : 0,
};
echo $number + $offset; // 40
}
总结与最佳实践
- 永远避免 eval() 处理动态字符串,尤其当数据来源不可控时;
- 优先选用经过审计的表达式引擎(如 Symfony ExpressionLanguage 或 msoos/php-expression-evaluator);
- 若逻辑极简,可结合正则白名单 + 手动运算,确保输入完全受控;
- 对所有输入执行严格验证:长度、字符集、操作符范围、数值范围;
- 在日志中记录异常表达式,便于监控潜在攻击尝试。
安全不是附加功能,而是设计起点——从第一行代码就拒绝“方便但危险”的捷径。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











