Pergunta

É possível criar uma variável variável apontando para um array ou para objetos aninhados?Os documentos php dizem especificamente que você não pode apontar para SuperGlobals, mas não está claro (pelo menos para mim) se isso se aplica a arrays em geral.

Aqui está minha tentativa com o array var var.

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

Aqui está um código simples para mostrar o que quero dizer com objeto var var.

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

Estou faltando algo óbvio aqui?

Foi útil?

Solução

Abordagem de elemento de matriz:

  • Extraia o nome do array da string e armazene-o em $arrayName.
  • Extraia o índice do array da string e armazene-o em $arrayIndex.
  • Analise-os corretamente em vez de como um todo.

O código:

$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];

Abordagem de propriedades de objeto:

  • Exploda a string que contém a classe e a propriedade que você deseja acessar por seu delimitador (->).
  • Atribua essas duas variáveis ​​a $class e $property.
  • Analise-os separadamente em vez de como um todo var_dump()

O código:

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

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

Funciona!

Outras dicas

Usar = & Para atribuir por referência:

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

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

 print $arrayVarTest;

Dentro echo $arrayTest[1]; o nome do vars é $arrayTest com um índice de matriz de 1, e não $arrayTest[1]. Os colchetes são "palavras -chave" PHP. O mesmo com a notação do método e o -> operador. Então você precisará se separar.

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

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

O que você quer fazer parece mais como avaliar o código PHP (eval()). Mas lembre -se: avaliar é mau. ;-)

Não, você não pode fazer isso. Você só pode fazer isso com nomes de variáveis, objetos e funções.

Exemplo:

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

As alternativas podem ser via avaliar () ou fazendo pré-processamento.

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

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

Ou seja, se você tiver certeza do que será a entrada.

Ao pré-processamento:

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top