0

i have an array with some info but i am trying to implement a way to access array dynamically with variable variables but i have no idea how, because php interprets that the whole string is a variable and not a variable with an associative key.

my example code:

$myArrayWithData = ["info" => 1];
$myvarvarArray = "myArrayWithData['info']";
print_r($$myvarvarArray);

expected behavior:

1

Actual Behavior:

`"Notice: Undefined variable: myArrayWithData['info']"`

i don want to hardcode indexes because i am trying to create a twig function that creates the array index path by a string and i am not able to predict the array Keys.

$myvarvarArray = "myArrayWithData"
print_r($$myvarvarArray["info"]); #hardcoded index

edit: my function can add more than 1 index

/**
     * add a value to your twig array instead of using merge
     *
     * @param $object  Array or object(public access) to set a new value
     * @param string $context object complete path where value will be setted example "children.grandchildren.info"
     * @param $value value to be inserted
     * 
     */ 
    public function enhancedMerge($object, $contexts, $value){
        $contexts = explode('.', $contexts);
        $newObject = $object;
        $path = '';

        foreach($contexts as $key => $context){
            $objectWithPath = 'newObject' . $path;
            $contextIsArray = is_array(${$objectWithPath}) ? true : false;
            if($contextIsArray){
                $path .= "['" . $context . "']";
            }else{
                $path .= "->" . $context;
            }
        }
        $objectWithPath = $newObject . $path;
        $$objectWithPath = $value;

        return $$newObject;
    }
DarkBee
  • 16,592
  • 6
  • 46
  • 58
Erick Est
  • 19
  • 3
  • 1
    Variable variables seem unnecessary here. Are you accessing multiple arrays? Or just multiple keys within this one array? – Alex Howansky Apr 03 '23 at 19:29
  • Thanks for the update. Do you mean it could be something like `$arr["index1"]["index2"]["index3"]`, but you don't know how many levels there are? – ADyson Apr 03 '23 at 19:44
  • Very confused as to what you're trying to accomplish here. Instead of typing `$arr['foo']['bar'] = 'baz';` in PHP, you want to type `arr.foo.bar = baz` in Twig? What is this function supposed to return? – Alex Howansky Apr 03 '23 at 19:44
  • this function tries to replace twig merge function that cannot add values when a variable has multiple index. And it's too hard to add the value with multiples array merge in twig. in twig it's imposible to do this: `{% set form.children.media.vars.myId = 10 %}` so. i want to make a solution like this `{% set form = form|enhanced_merge("children.media.vars.myId", 10) %}` – Erick Est Apr 03 '23 at 19:54
  • but i have an idea how to access with a recursive function. – Erick Est Apr 03 '23 at 20:01
  • Unsure why you've opened a new question instead of providing more information/details on your [initial question](https://stackoverflow.com/questions/75903506/php-variable-variables-doesnt-work-as-expected-with-arrays)? – DarkBee Apr 04 '23 at 05:25
  • By the way, `$contextIsArray = is_array(${$objectWithPath}) ? true : false; if($contextIsArray){` can be simplified to `if (is_array(${$objectWithPath})) {` ...there is no reason to declare the single-use variable. – mickmackusa Apr 04 '23 at 05:27

1 Answers1

1

Can I access array key with variable variables?

Short answer: No.

However, we can access them using reference variables like this answer.

My function now adds values to array twigs

public function enhancedMerge($object, $contexts, $value)
{
    $contexts = explode('.', $contexts);
    $elemCount = count($contexts); 

    $current = &$object;
    foreach ($contexts as $key => $context) {
        if (is_array($current)) {
            $current =  &$current[$context];
        } elseif ($key != $elemCount-1) {
            $current =  &$current->$context;
        }
    }

    $backup = $current;
    $current = $value; #set new value and modify $object by reference 

    return $object;
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Erick Est
  • 19
  • 3
  • If `$object` is an object, then it is inherently modifiable by reference. What is the point of declaring `$backup` if it is never accessed? Is it safe to assume that the "value" to be assigned by this method will always be scalar (string/integer/float/boolean)? I don't see your code properly handling the possibility of the value being an array. Rather than checking `$key != $elemCount-1` in a loop, you can more simply `array_pop()` the last value from the array prior to looping. – mickmackusa Apr 05 '23 at 04:30