Переменные Переменные, указывающие на массивы или вложенные объекты - PullRequest
3 голосов
/ 10 января 2010

Возможно ли создать переменную переменную, указывающую на массив или на вложенные объекты? В документации php говорится, что вы не можете указать на 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});    

Я что-то упускаю здесь очевидное?

Ответы [ 4 ]

5 голосов
/ 10 января 2010

Подход к элементу массива :

  • Извлечение имени массива из строки и сохранение его в $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];

Подход свойств объекта :

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

код:

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

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

Работает!

1 голос
/ 10 января 2010

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

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

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

 print $arrayVarTest;
0 голосов
/ 10 января 2010

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

Пример:

 $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);
0 голосов
/ 10 января 2010

В echo $arrayTest[1]; имя переменной $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 - это зло. ; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...