В вашем примере 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;");
}
Я использовал это в другом ответе на вопрос , чтобы надежно преобразовать строку, содержащую информацию массива PHP, в массив .