Переменные Переменные, указывающие на массивы или вложенные объекты

StackOverflow https://stackoverflow.com/questions/2036547

Вопрос

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

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

Это было полезно?

Решение

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

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

Оно работает!

Другие советы

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

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

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

 print $arrayVarTest;

В 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()).Но помни:Эваль - это зло.;-)

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

Пример:

 $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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top