Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用eval从字符串计算数学表达式_Php_Math_Eval - Fatal编程技术网

Php 使用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行上的代码 有人知道这个问题的解决方案吗。虽然我

我想从字符串计算数学表达式。我已经读到解决这个问题的方法是使用eval()。但当我尝试运行以下代码时:

<?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