2010-01-10 4 views
3

Возможно ли создать переменную переменную, указывающую на массив или на вложенные объекты? В php docs указано, что вы не можете указывать на SuperGlobals, но неясно (по крайней мере, мне), если это относится к массивам в целом.Переменные переменные, указывающие на массивы или вложенные объекты

Вот моя попытка массива var var.

 // Array Example 
    $arrayTest = array('value0', 'value1'); 
    ${arrayVarTest} = 'arrayTest[1]'; 
    // This returns the correct 'value1' 
    echo $arrayTest[1]; 
    // This returns null 
    echo ${$arrayVarTest}; 

Вот какой простой код, чтобы показать, что я имею в виду под объектом var var.

 ${OBJVarVar} = 'classObj->obj'; 
    // This should return the values of $classObj->obj but it will return null 
    var_dump(${$OBJVarVar});  

Я пропустил что-то очевидное здесь?

+0

Обновлен мой ответ, чтобы включить проблему с индексом массива, я неправильно понял вас и подумал, что вы контролируете это! – johnnyArt

+0

Если переменная-переменная является ответом, вы, вероятно, задаете неправильный вопрос. Почему бы просто не использовать назначение по ссылке? –

ответ

5

Элемент массива подход:

  • Извлечение имени массива из строки и хранить это в $arrayName.
  • Извлечь индекс массива из строки и сохранить его в $arrayIndex.
  • Соберите их правильно, а не в целом.

Код:

$arrayTest = array('value0', 'value1'); 
$variableArrayElement = 'arrayTest[1]'; 
$arrayName = substr($variableArrayElement,0,strpos($variableArrayElement,'[')); 
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement); 

// This returns the correct 'value1' 
echo ${$arrayName}[$arrayIndex]; 

свойства объектный подход:

  • Explode строку, содержащую класс и свойство, которое вы хотите получить доступ к своим разделителем (->).
  • Назначьте эти две переменные $class и $property.
  • Разбираем их по отдельности, а не в целом по var_dump()

Код:

$variableObjectProperty = "classObj->obj"; 
list($class,$property) = explode("->",$variableObjectProperty); 

// This now return the values of $classObj->obj 
var_dump(${$class}->{$property});  

Это работает!

+0

Спасибо! Именно то, что я пытался достичь. Отлично работает. – Bookworm

0

В echo $arrayTest[1]; имя vars составляет $arrayTest с индексом массива 1, а не $arrayTest[1]. Скобки - это ключевые слова PHP. То же самое со знаком метода и оператором ->. Поэтому вам нужно разделиться.

// bla[1] 
$arr = 'bla'; 
$idx = 1; 
echo $arr[$idx]; 

// foo->bar 
$obj = 'foo'; 
$method = 'bar'; 
echo $obj->$method; 

Что вы хотите сделать больше походит оценки PHP код (eval()). Но помните: eval - это зло. ;-)

0

Нет, вы не можете этого сделать. Вы можете делать это только с именами переменных, объектов и функций.

Пример:

$objvar = 'classObj'; 
var_dump(${$OBJVarVar}->var); 

Альтернативы могут быть с помощью Eval() или путем делать предварительную обработку.

$arrayTest = array('value0', 'value1'); 
$arrayVarTest = 'arrayTest[1]'; 

echo eval('return $'.$arrayVarTest.';'); 
eval('echo $'.$arrayVarTest.';'); 

То есть, если вы очень уверены в том, что будет входом.

По предварительной обработки:

function varvar($str){ 
    if(strpos($str,'->') !== false){ 
    $parts = explode('->',$str); 
    global ${$parts[0]}; 
    return $parts[0]->$parts[1]; 
    }elseif(strpos($str,'[') !== false && strpos($str,']') !== false){ 
    $parts = explode('[',$str); 
    global ${$parts[0]}; 
    $parts[1] = substr($parts[1],0,strlen($parts[1])-1); 
    return ${$parts[0]}[$parts[1]]; 
    }else{ 
    return false; 
    } 
} 

$arrayTest = array('value0', 'value1'); 
$test = 'arrayTest[1]'; 
echo varvar($test); 
1

Использование = & для назначения по ссылке:

$arrayTest = array('value0', 'value1'); 
$arrayVarTest = &$arrayTest[1]; 

$arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference 

print $arrayVarTest; 
+0

Вопрос не спрашивает о ссылках. – mauris

+0

@mauris: возможно, но найти этот ответ, в то время как googling дал мне решение, которое я искал;) – hugsbrugs