我不断得到
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);
您正在构建的字符串需要在
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']);
我得意忘形,思考如何改进它,这实际上可能不是你问题的答案,而是更多的思考。我看到两种解决方案,而且都是侵入性的。
当然,如果您的公式仅使用“变量”(如示例中的
((WILL*0.8)/2.5)+(LEVEL/4)
所示),则这两种解决方案仅适用于所有情况。如果您有更复杂的公式,则必须调整我的解决方案。
假设公式在您的控制之下而不是用户提供的,您可以通过不在评估代码中注入所有输入而仅注入公式来改进评估。这样您就不必转义输入,只需确保公式在语法上正确。
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 框架,表达式语言组件可以单独使用。这可能是一个很大的变化,这取决于您现有的代码库的外观。如果您的项目中没有使用过 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'],
)
);
正如我所说,这可能是一个巨大的变化,如果您还不了解,您可能需要熟悉作曲家。