Variable Variables Pointing to Arrays or Nested Objects

后端 未结 5 1556
南方客
南方客 2020-12-04 03:01

Is it possible to create a variable variable pointing to an array or to nested objects? The php docs specifically say you cannot point to SuperGlobals but its unclear (to me

相关标签:
5条回答
  • 2020-12-04 03:25

    there is a dynamic approach for to many nested levels:

    $attrs = ['level1', 'levelt', 'level3',...];
    $finalAttr = $myObject;
    foreach ($attrs as $attr) {
        $finalAttr = $finalAttr->$attr;
    }
    return $finalAttr;
    
    0 讨论(0)
  • 2020-12-04 03:27

    Array element approach:

    • Extract array name from the string and store it in $arrayName.
    • Extract array index from the string and store it in $arrayIndex.
    • Parse them correctly instead of as a whole.

    The code:

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

    Object properties approach:

    • Explode the string containing the class and property you want to access by its delimiter (->).
    • Assign those two variables to $class and $property.
    • Parse them separately instead of as a whole on var_dump()

    The code:

    $variableObjectProperty = "classObj->obj";
    list($class,$property)  = explode("->",$variableObjectProperty);
    
    // This now return the values of $classObj->obj
    var_dump(${$class}->{$property});    
    

    It works!

    0 讨论(0)
  • 2020-12-04 03:27

    Use = & to assign by reference:

     $arrayTest = array('value0', 'value1');
     $arrayVarTest = &$arrayTest[1];
    
     $arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference
    
     print $arrayVarTest;
    
    0 讨论(0)
  • 2020-12-04 03:30

    Nope you can't do that. You can only do that with variable, object and function names.

    Example:

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

    Alternatives can be via eval() or by doing pre-processing.

    $arrayTest = array('value0', 'value1');
    $arrayVarTest = 'arrayTest[1]';
    
    echo eval('return $'.$arrayVarTest.';');
    eval('echo $'.$arrayVarTest.';');
    

    That is if you're very sure of what's going to be the input.

    By pre-processing:

    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 讨论(0)
  • 2020-12-04 03:39

    In echo $arrayTest[1]; the vars name is $arrayTest with an array index of 1, and not $arrayTest[1]. The brackets are PHP "keywords". Same with the method notation and the -> operator. So you'll need to split up.

    // bla[1]
    $arr = 'bla';
    $idx = 1;
    echo $arr[$idx];
    
    // foo->bar
    $obj = 'foo';
    $method = 'bar';
    echo $obj->$method;
    

    What you want to do sounds more like evaluating PHP code (eval()). But remember: eval is evil. ;-)

    0 讨论(0)
提交回复
热议问题