PHP动态访问变量值
我想动态访问变量的值,假设我有这个数组:PHP动态访问变量值,php,variables,Php,Variables,我想动态访问变量的值,假设我有这个数组: $aData = array( 'test' => 123 ); 打印测试键值的标准方法是: print $aData['test']; 但是,如果我必须使用变量的字符串表示(出于动态目的) 如何实现打印名为test的aData键?下面提供的两个示例都不起作用 print $$sItem; print eval($sItem); 解决方案是什么?在您的情况下,唯一的解决方案是使用 但是在做这件事的时候请非常小心!Eval将计算(并执行)作
$aData = array(
'test' => 123
);
打印测试
键值的标准方法是:
print $aData['test'];
但是,如果我必须使用变量的字符串表示(出于动态目的)
如何实现打印名为test
的aData
键?下面提供的两个示例都不起作用
print $$sItem;
print eval($sItem);
解决方案是什么?在您的情况下,唯一的解决方案是使用 但是在做这件事的时候请非常小心!Eval将计算(并执行)作为PHP传递给它的任何参数。因此,如果您将用户提供的内容提供给它,那么任何人都可以在您的服务器上执行任何PHP代码,这无疑是一个大峡谷大小的安全漏洞
编辑:您必须在
$sItem
变量中添加一个“print”或“echo”。它必须在$sItem
($sItem='echo$aData[\'test\'];
)中,或者您必须这样编写Eval()
:Eval('echo'.$sData)您可以像普通数组一样使用它:
$key = "test";
print $aData[$key];
同样地,$aData
本身也可以是较大数组存储中的一个条目
作为替代方案,可以使用正则表达式提取潜在的数组键,并使用引用遍历匿名数组(在您的问题中应该提到,if)。请参阅和类似主题
就我个人而言,我使用这样的构造来利用动态变量路径,比如
varname[keyname]
(类似于PHP解释GET参数的方式)。这只是绵羊服装中的评估(尽管不同意评估恐慌的说法):
您的评估示例缺少返回值:
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,实际上是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;
}
然后,您就可以使用它,它也可以与更复杂的键一起使用:
$aData['test'] = 'foo';
$aData['te\\\'[]st']['more'] = 'bar';
$sItem = '$aData[\'test\']';
$vValue = NULL;
if (validate_tokens($sItem, array(309, 315, '[', ']')))
{
$vValue = eval("return $sItem;");
}
我用这个来回答这个问题
如其他aldready解释的那样,请谨慎使用。如果您已经(或能够)将数组名称和键输入到单独的变量中,则无需进行评估:
$aData = array(
'test' => 123
);
$arrayname = 'aData';
$keyname = 'test';
print ${$arrayname}[$keyname]; // 123
你可以用这个方法
function getRecursive($path, array $data) {
// transform "foo['bar']" and 'foo["bar"]' to "foo[bar]"
$path = preg_replace('@\[(?:"|\')(.+)(?:"|\')\]@Uis', '[\1]', $path);
// get root
$i = strpos($path, '[');
$rootKey = substr($path, 0, $i);
if (!isset($data[$rootKey])) {
return null;
}
$value = $data[$rootKey];
$length = strlen($path);
$currentKey = null;
for (; $i < $length; ++$i) {
$char = $path[$i];
switch ($char) {
case '[':
if ($currentKey !== null) {
throw new InvalidArgumentException(sprintf('Malformed path, unexpected "[" at position %u', $i));
}
$currentKey = '';
break;
case ']':
if ($currentKey === null) {
throw new InvalidArgumentException(sprintf('Malformed path, unexpected "]" at position %u', $i));
}
if (!isset($value[$currentKey])) {
return null;
}
$value = $value[$currentKey];
if (!is_array($value)) {
return $value;
}
$currentKey = null;
break;
default:
if ($currentKey === null) {
throw new InvalidArgumentException(sprintf('Malformed path, unexpected "%s" at position %u', $char, $i));
}
$currentKey .= $char;
break;
}
}
if ($currentKey !== null) {
throw new InvalidArgumentException('Malformed path, must be and with "]"');
}
return $value;
}
函数getRecursive($path,array$data){
//将“foo['bar']”和“foo['bar']”转换为“foo[bar]”
$path=preg\u replace('@\[(?:“\\”)(.+)(?:“\\”)\]@Uis','[\1]',$path);
//扎根
$i=strpos($path,[');
$rootKey=substr($path,0,$i);
如果(!isset($data[$rootKey])){
返回null;
}
$value=$data[$rootKey];
$length=strlen($path);
$currentKey=null;
对于(;$i<$length;++$i){
$char=$path[$i];
交换机($char){
案例“[”:
如果($currentKey!==null){
抛出新的InvalidArgumentException(sprintf('格式错误的路径,位置%u'处意外出现“[”,$i));
}
$currentKey='';
打破
案例']':
如果($currentKey==null){
抛出新的InvalidArgumentException(sprintf('格式错误的路径,位置%u'处意外出现“]”,$i));
}
如果(!isset($value[$currentKey])){
返回null;
}
$value=$value[$currentKey];
如果(!是_数组($value)){
返回$value;
}
$currentKey=null;
打破
违约:
如果($currentKey==null){
抛出新的InvalidArgumentException(sprintf('格式错误的路径,位置%u'处意外的“%s”,$char,$i));
}
$currentKey.=$char;
打破
}
}
如果($currentKey!==null){
抛出新的InvalidArgumentException('格式错误的路径,必须是且带有“]”);
}
返回$value;
}
除了您可能指的是打印$aData[$key],而不是$aData[$test之外,这是目前为止最好的解决方案+1如果您忽略了被问到的问题,那么这是最好的解决方案,是的!:)+1.我认为这是唯一合理、有效的解决办法。无论其他人建议如何使用
eval
,他们都不会返回键test
。也许某些正则表达式字符串解析可以实现提取密钥,但eval永远无法根据OP获取字符串的方式来实现这一点。@JanHančič被询问的是密钥,而不是结果。两个eval
示例都无法检索密钥。hakre的字符串解析解决方案确实有效,但这是一个迂回的过程。为什么你要把密钥分配给一个字符串变量的子字符串,然后必须遍历整个字符串来获取密钥,而你可以随时准备好密钥。@JanHančič也许,你可能是对的。如果问题是访问该值,那么您是对的。但是,我们必须等待OP的回复,看看我是否理解。:)根据他的问题,这是。@all:谢谢你们,从我的计划来看(在大图中),使用eval函数对我来说是最好的解决方案。。。我只是忘了使用return,这是个好方法。但是,一个preg\u match\u all
就足以在
$aData['test'] = 'foo';
$aData['te\\\'[]st']['more'] = 'bar';
$sItem = '$aData[\'test\']';
$vValue = NULL;
if (validate_tokens($sItem, array(309, 315, '[', ']')))
{
$vValue = eval("return $sItem;");
}
$sItem = '$aData[\'test\']';
eval('$someVar = '.$sItem.';');
echo $someVar;
$aData = array(
'test' => 123
);
$arrayname = 'aData';
$keyname = 'test';
print ${$arrayname}[$keyname]; // 123
function getRecursive($path, array $data) {
// transform "foo['bar']" and 'foo["bar"]' to "foo[bar]"
$path = preg_replace('@\[(?:"|\')(.+)(?:"|\')\]@Uis', '[\1]', $path);
// get root
$i = strpos($path, '[');
$rootKey = substr($path, 0, $i);
if (!isset($data[$rootKey])) {
return null;
}
$value = $data[$rootKey];
$length = strlen($path);
$currentKey = null;
for (; $i < $length; ++$i) {
$char = $path[$i];
switch ($char) {
case '[':
if ($currentKey !== null) {
throw new InvalidArgumentException(sprintf('Malformed path, unexpected "[" at position %u', $i));
}
$currentKey = '';
break;
case ']':
if ($currentKey === null) {
throw new InvalidArgumentException(sprintf('Malformed path, unexpected "]" at position %u', $i));
}
if (!isset($value[$currentKey])) {
return null;
}
$value = $value[$currentKey];
if (!is_array($value)) {
return $value;
}
$currentKey = null;
break;
default:
if ($currentKey === null) {
throw new InvalidArgumentException(sprintf('Malformed path, unexpected "%s" at position %u', $char, $i));
}
$currentKey .= $char;
break;
}
}
if ($currentKey !== null) {
throw new InvalidArgumentException('Malformed path, must be and with "]"');
}
return $value;
}