首页 > 解决方案 > 如何修复我的 eval()'d 代码行:1 个问题

问题描述

我不断得到

file: C:\xampp\htdocs\doit.php(45) : eval()'d code line: 1

我已经搜索了该站点,但找不到适合我的修复程序这是我正在使用的代码,它给出了问题

     $ec = "\$sucrate=" . str_replace(array("LEVEL", "EXP", "WILL", "IQ"), array($player['level'], $player['exp'], $player['will'], $player['IQ']), $r['crimePERCFORM']) . ";";
 eval($ec);

标签: phpeval

解决方案


我被冲昏了头脑,并考虑过如何改进它,这实际上可能不是您问题的答案,而是更多的思考。我看到了两种解决方案,而且都具有侵入性。

当然,如果您的公式仅使用“变量”,例如您的示例中的((WILL*0.8)/2.5)+(LEVEL/4). 如果您有更复杂的公式,您将不得不调整我的解决方案。

包装 eval 并且不要在 eval 代码中注入所有输入

假设公式在您的控制之下并且不是用户提供的,您可以通过不在您的评估代码中注入所有输入而只注入公式来改进您的评估。这样你就不必逃避输入,你只需要确保公式在语法上是正确的。

function calculateFormula($_vars, $_values, $_formula) {
    // This transforms your formula into PHP code which looks
    // like this: (($WILL*0.8)/2.5)+($LEVEL/4)
    $_cleanFormula = str_replace(
        $_vars,
        array_map(function($v) { return '$' . $v; }, $_vars),
        $_formula
    );

    // create the $WILL, $LEVEL, $IQ and $EXP variables in the local scope
    extract(array_combine($_vars, $_values));

    // execute the PHP-formula
    return eval('return ' . $_cleanFormula . ';');
}

// Use it like this, instead of eval
$sucrate = calculateFormula(
    array("LEVEL", "EXP", "WILL", "IQ"), 
    array($player['level'], $player['exp'], $player['will'], $player['IQ']),
    $r['crimePERCFORM']);

这仍然使用 eval,所以从安全角度来看,这将是最糟糕的解决方案。但这将是最接近您现在所拥有的。

使用 Symfony 的表达式语言

更安全的选择是使用symfony 的表达式语言组件之类的东西。现在您的应用程序中不需要整个 symfony 框架,表达式语言组件可以单独使用。这可能是一个很大的变化,这取决于您现有代码库的外观。如果您没有在项目中使用过composer 或命名空间,则此更改可能太大。

require_once __DIR__ . '/vendor/autoload.php';

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

$expressionLanguage = new ExpressionLanguage();

$sucrate = $expressionLanguage->evaluate(
    $r['crimePERCFORM'],
    array(
        "LEVEL" => $player['level'],
        "EXP" => $player['exp'],
        "WILL" => $player['will'],
        "IQ" => $player['IQ'],
    )
);

正如我所说,这可能是一个巨大的变化,如果你还不知道的话,你可能必须熟悉作曲家。


推荐阅读