0

$str='input_arr["username"]';

$input_arr=array();

$$str='abcd';

print_r($input_arr);

When I run the above code it only prints Array().

I expected it to print Array([username]=>'abcd')

What am I doing wrong?

This is in php 4 by the way.

Thanks a lot.

Edit:What am I trying to do?

$input_arr is supposed to be a static variable to hold validated user input.However, I only recently realised that php4.3 doesnt support self::$input_arr so I had to edit my script to bar($input_arr['name'],$value); so that I can save the value to a static variable in bar();since $input_arr['name'] does not exists in the current scope, I had to make it a string.

3
  • 4
    You are using arrays wrong. Variable variables are a pain to debug. What exactly are you trying to do? I am sure there's a better way to do it. Commented Aug 17, 2010 at 13:21
  • I did some basic tests with this and you're right, it doesn't work. On my end it stops working when I try fiddling with the elements of the array through variable variables. If I mess around with the array as a whole, everything I try works just fine. But it sure looks like you're crossing the lake to get the water here, what exactly are you trying to accomplish? Commented Aug 17, 2010 at 13:46
  • I have added some information on what I am trying to do. Commented Aug 17, 2010 at 14:08

3 Answers 3

3

I would strive to avoid eval at all costs. Use PHP's built-in tokenizer.

<?php
error_reporting(-1);
$input = array(3 => array(5 => 'some value'));

echo '$input: '; var_dump($input);

echo '$input[3][5] (directly): '; var_dump($input[3][5]);

$str = '$input[3][5]';
echo "$str (as a variable variable): "; var_dump($$str);

echo "$str (using eval - don't use this!): "; var_dump(eval("return $str;"));

$var = null;
foreach (token_get_all("<?php $str") as $token) {
    if (isset($token[1]) && $token[1] === '<?php') {
        continue;
    }
    if (isset($token[0]) && $token[0] === T_VARIABLE) {
        $varName = substr($token[1], 1);
        $var = $$varName;
    } else if ($token === '[') {
        $currentIndex = null;
    } else if (isset($token[0]) && $token[0] === T_LNUMBER) {
        $currentIndex = $token[1];
    } else if ($token === ']') {
        $var = $var[$currentIndex];
    } else {
        // Handle/complain about unrecognized input.
    }
}
echo "$str (using tokenizer): "; var_dump($var);

The output:

$input: array(1) {
  [3]=>
  array(1) {
    [5]=>
    string(10) "some value"
  }
}
$input[3][5] (directly): string(10) "some value"
$input[3][5] (as a variable variable): 
Notice: Undefined variable: $input[3][5] in - on line 10
NULL
$input[3][5] (using eval - don't use this!): string(10) "some value"
$input[3][5] (using tokenizer): string(10) "some value"
Sign up to request clarification or add additional context in comments.

2 Comments

@Mystery person: care to explain the downvote? I think this is the safest approach (keeping in mind that variable variables still smell like bad code design) and I made it clear that eval is evil. Are you objecting to the use of the tokenizer instead of eval, perhaps?
someone going nuts on the downvotes :p code looked clean to me, upvoted.
0

It's still difficult to tell what you're trying to do, but it sounds like you want $str to determine where inside $input_arr a piece of data lives. If so, you should store only the array key(s) in $str, not a string representation of the code.

In your last example, it's as simple as setting $str = 'name' and then using $input_arr[$str] to access $input['name']. In the first case, you could use an array $keys = array(3,5) instead of $str, and then $input_arr[$keys[0]][$keys[1]] would be equivalent to $input_arr[3][5].

Comments

0

It could work with 2 variables if you really want this. Even better if you use a reference to the array instead of a variable variable.

$input_arr = Array();

function somefunction($array, $key)
{
    ${$array}[$key] = 'abcd';
}

function betterfunction(&$array, $key)
{
    $array[$key] = 'abcd';
}

somefunction('input_arr', 'username');
betterfunction($input_arr, 'username');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.