你的eval例如缺少返回值:
print eval("return $sItem;");
应该这样做:
$aData['test'] = 'foo';
$sItem = '$aData[\'test\']';
print eval("return $sItem;"); # foo
但不建议正常使用eval。你可以用它进入地狱的厨房,因为eval是邪恶的。
而不只是解析字符串,返回值:
$aData['test'] = 'foo';
$sItem = '$aData[\'test\']';
$r = sscanf($sItem, '$%[a-zA-Z][\'%[a-zA-Z]\']', $vName, $vKey);
if ($r === 2)
{
$result = ${$vName}[$vKey];
}
else
{
$result = NULL;
}
print $result; # foo
这可以用正则表达式的一些其他形式进行为好。
由于您的语法与PHP非常接近,实际上它的一个子集,如果您想在使用eval之前验证输入,您可以执行一些备选操作。该方法是检查PHP令牌,并只允许一个子集。这不验证字符串(如语法和变量是否实际设置),但使得它更加严格:
function validate_tokens($str, array $valid)
{
$vchk = array_flip($valid);
$tokens = token_get_all(sprintf('<?php %s', $str));
array_shift($tokens);
foreach($tokens as $token)
if (!isset($vchk[$token])) return false;
return true;
}
你只要给有效的令牌给该函数的数组。这些都是PHP令牌,你的情况的是:
T_LNUMBER (305) (probably)
T_VARIABLE (309)
T_CONSTANT_ENCAPSED_STRING (315)
然后你才可以使用它,并将它与更复杂的按键的作品,以及:
$aData['test'] = 'foo';
$aData['te\\\'[]st']['more'] = 'bar';
$sItem = '$aData[\'test\']';
$vValue = NULL;
if (validate_tokens($sItem, array(309, 315, '[', ']')))
{
$vValue = eval("return $sItem;");
}
我的问题another answer使用该reliably convert string containing PHP array info to array。
@all:感谢你们所有人,从我计划做的事情(大图)最好的解决方案,我使用eval函数...我只是忘记使用返回 – nabizan