我如何修复我的 eval() 代码行:1 个问题

问题描述 投票:0回答:2

我不断得到

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);
php eval
2个回答
0
投票

您正在构建的字符串需要在

str_replace
'd 字符串周围加上引号(可能还需要另一个 string_replace 对来防止引号问题)。

示例:

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

但是,虽然这应该可以解决您的问题,但几乎从来没有使用

eval
的好例子。无论您采取什么“保护措施”,允许任何人在您的服务器上运行任何代码,就好像它是由您编写的一样,它肯定会让您的代码容易受到某种远程执行黑客的攻击。

这会做完全相同的事情,只是用替换的值设置

$sucrate
变量。

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

0
投票

我得意忘形,思考如何改进它,这实际上可能不是你问题的答案,而是更多的思考。我看到两种解决方案,而且都是侵入性的。

当然,如果您的公式仅使用“变量”(如示例中的

((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'],
    )
);

正如我所说,这可能是一个巨大的变化,如果您还不了解,您可能需要熟悉作曲家。

© www.soinside.com 2019 - 2024. All rights reserved.