Php 使用eval从字符串计算数学表达式
我想从字符串计算数学表达式。我已经读到解决这个问题的方法是使用eval()。但当我尝试运行以下代码时:Php 使用eval从字符串计算数学表达式,php,math,eval,Php,Math,Eval,我想从字符串计算数学表达式。我已经读到解决这个问题的方法是使用eval()。但当我尝试运行以下代码时: <?php $ma ="2+10"; $p = eval($ma); print $p; ?> 它给了我以下错误: 分析错误:语法错误,意外的$end in C:\xampp\htdocs\eclipseWorkspaceWebDev\MandatoryHandinSite\tester.php(4) :eval()'d第1行上的代码 有人知道这个问题的解决方案吗。虽然我
<?php
$ma ="2+10";
$p = eval($ma);
print $p;
?>
它给了我以下错误:
分析错误:语法错误,意外的$end in
C:\xampp\htdocs\eclipseWorkspaceWebDev\MandatoryHandinSite\tester.php(4)
:eval()'d第1行上的代码
有人知道这个问题的解决方案吗。虽然我不建议对此使用
eval
(这不是解决方案),但问题是eval
需要完整的代码行,而不仅仅是片段
$ma ="2+10";
$p = eval('return '.$ma.';');
print $p;
你应该做你想做的
更好的解决方案是为数学表达式编写标记器/解析器。下面是一个非常简单的基于正则表达式的示例:
$ma = "2+10";
if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', $ma, $matches) !== FALSE){
$operator = $matches[2];
switch($operator){
case '+':
$p = $matches[1] + $matches[3];
break;
case '-':
$p = $matches[1] - $matches[3];
break;
case '*':
$p = $matches[1] * $matches[3];
break;
case '/':
$p = $matches[1] / $matches[3];
break;
}
echo $p;
}
eval
将给定代码计算为PHP
。这意味着它将以PHP代码段的形式执行给定的参数
要更正代码,请使用以下命令:
$ma ="print (2+10);";
eval($ma);
求值表达式应以“;”结尾 试试这个:
$ma ="2+10;";
$p = eval($ma);
print $p;
顺便说一下,这超出了范围,但是'eval'函数不会返回表达式的值。eval('2+10')不会返回12。
如果您想让它返回12,您应该求值('return2+10;') 看看这个
我在一个会计系统中使用它,在这个系统中,您可以在金额输入字段中编写数学表达式
例子
密码
解决了
<?php
function evalmath($equation)
{
$result = 0;
// sanitize imput
$equation = preg_replace("/[^a-z0-9+\-.*\/()%]/","",$equation);
// convert alphabet to $variabel
$equation = preg_replace("/([a-z])+/i", "\$$0", $equation);
// convert percentages to decimal
$equation = preg_replace("/([+-])([0-9]{1})(%)/","*(1\$1.0\$2)",$equation);
$equation = preg_replace("/([+-])([0-9]+)(%)/","*(1\$1.\$2)",$equation);
$equation = preg_replace("/([0-9]{1})(%)/",".0\$1",$equation);
$equation = preg_replace("/([0-9]+)(%)/",".\$1",$equation);
if ( $equation != "" ){
$result = @eval("return " . $equation . ";" );
}
if ($result == null) {
throw new Exception("Unable to calculate equation");
}
echo $result;
// return $equation;
}
$a = 2;
$b = 3;
$c = 5;
$f1 = "a*b+c";
$f1 = str_replace("a", $a, $f1);
$f1 = str_replace("b", $b, $f1);
$f1 = str_replace("c", $c, $f1);
evalmath($f1);
/*if ( $equation != "" ){
$result = @eval("return " . $equation . ";" );
}
if ($result == null) {
throw new Exception("Unable to calculate equation");
}
echo $result;*/
?>
当无法控制字符串参数时,使用函数是非常危险的
尝试安全的数学公式计算。我最近创建了一个PHP包,它提供了一个
math\u eval
helper函数。它完全满足您的需要,无需使用潜在不安全的eval
功能
您只需传入数学表达式的字符串版本,它就会返回结果
$two = math_eval('1 + 1');
$three = math_eval('5 - 2');
$ten = math_eval('2 * 5');
$four = math_eval('8 / 2');
您还可以传入变量,如果需要,这些变量将被替换
$ten = math_eval('a + b', ['a' => 7, 'b' => 3]);
$fifteen = math_eval('x * y', ['x' => 3, 'y' => 5]);
链接:此方法有两个主要缺点:
- 安全性,php脚本由eval函数进行评估。这很糟糕, 尤其是当用户想要注入恶意代码时
- 复杂性
formula解释器的实例
$Formula解释器=新的Formula解释器(“x+y”,“x”=>10,“y”=>20”);
使用execute()
方法解释公式。它将返回结果:
echo$formula解释器->执行();
一行
echo(新公式解释器(“x+y”,“x”=>10,“y”=>20]))->execute();
例子
#公式:速度=距离/时间
$speed=(新公式解释器(“距离/时间”[“距离”=>338,“时间”=>5]))->execute();
回声速度;
#委内瑞拉夜间加班(以小时计的普通工作日):(正常工资*工作月天数)/普通工作日
$parameters=[“正常工资”=>21000,“工作月天数”=>30,“正常工作日”=>8];
$VENEZUELAOTTART118Night加班=(新公式解释程序(((正常工资/工作月天数)/正常工作日,$parameters))->execute();
echo$Venezuelalott加班费;
#圆环区
$cicleArea=(新公式解释器(“3.1416*(radio*radio)”,[“radio”=>10]))->execute();
echo$cicleArea;
关于公式
它必须至少包含两个操作数和一个运算符
操作数的名称可以是大写或小写
到目前为止,数学函数如sin,cos,pow…还不包括在内。我正在努力把它们包括进来
如果您的公式无效,您将收到一条错误消息,如:错误,您的公式(单变量)无效。
参数的值必须是数字
如果你想,你可以改进它!
使用eval函数
你可以使用eval()
来破解一些东西,但是任何人都不应该使用eval来做任何事情。好的,谢谢。。如果我可以问的话,使用eval()有什么不好?@user68621:它非常不安全。$ma
字符串来自哪里?用户输入?如果我发送rmdir('/var/www')代码>或其他什么作为我的输入?啊,我明白你的意思:)是的$ma是用户输入。基本上,因为90%的时候它被用来评估从外部来源提取的代码,这是一个安全问题。9.9%的时间是人们处理问题时出错。最后的0.1%是一只我还没有见过的神秘独角兽,我仍然怀疑它的存在。此外,上述百分比忽略了黑客将eval()
代码注入易受攻击网页的绝大多数时间。这将显示一个空白页面,因为$p
变量为空。在内部添加echo
:$ma=“echo 2+10;”
@mansoulx,这正是上面回答中所说的(“返回2+10”)。我添加了一个更好的解决方案的建议。这不是最棒的,但我希望它能让你知道你需要做什么。我相信你可以搜索一个更好的解决方案。这真的很好,除了在我的函数中,我有24.5*12,它把第一个数字作为5,而不是24.5,因为它只寻找数字。用下面的替换模式为我做了诀窍(允许数字、空格和小数)-请注意,它会将数字与其中的空格进行匹配(即“201.5+11 2012=212.5”,因此如果不去掉这些空格(通过str_替换around$matches[1]
和$matches[3]
或类似方法),数学将无法完全正确地工作)。这完全取决于您的使用情况-这满足了我的需要。/([\d\.\s]+)([\+-\*\/])([\d\.\s]+)/
再进一步:/([\d\.\s]+)([\+-\*\/])(\-?[\d\.\s]+)/
将允许第二个数字为负值(例如在24.5*-4的情况下)。由于第二组没有f,这将被打破
$two = math_eval('1 + 1');
$three = math_eval('5 - 2');
$ten = math_eval('2 * 5');
$four = math_eval('8 / 2');
$ten = math_eval('a + b', ['a' => 7, 'b' => 3]);
$fifteen = math_eval('x * y', ['x' => 3, 'y' => 5]);
protected function getStringArthmeticOperation($value, $deduct)
{
if($value > 0){
$operator = '-';
}else{
$operator = '+';
}
$mathStr = '$value $operator $deduct';
eval("\$mathStr = \"$mathStr\";");
$userAvailableUl = eval('return '.$mathStr.';');
return $userAvailableUl;
}
$this->getStringArthmeticOperation(3, 1); //2