Oh yeah I wrote this a while back but never posted it, might be interesting to some:
Code: Select all
<?php
// Want to set key's value to 10 via variable variable
$target = array('key' => 5);
$varvar = 'target';
// This should have done it
$$varvar['key'] = 10;
echo $$varvar['key'], '<br />'; // Outputs: 10
echo print_r($target, true), '<br />'; // Outputs: Array ( [key] => 5 )
echo print_r($varvar, true), '<br />'; // Sanity check; outputs: target
echo print_r(${'target'}, true), '<br />'; // Sanity check; Outputs: Array ( [key] => 5 )
// Where has 10 actually been stored?!
print_r(get_defined_vars()); // Reveals a variable 't' has been defined with 10
echo $t; // Outputs: 10
$varvar = 'parget';
$$varvar['key'] = 9;
echo $p; // Outputs: 9
$varvar = 'target';
// {$$varvar['key']} = 9; // syntax error
// $$varvar{['key']} = 9; // syntax error
${$varvar}['key'] = 8;
echo $target['key']; // Outputs: 8, YAY!
This is what I think is happening here:
Code: Select all
$varvar = 'target';
$$varvar['key'] = 10;
$varvar['key'] is evaluated first. The array subscript is used as string offset and, PHP being a loosely typed language, 'key' is automatically casted to int.
Code: Select all
$result = (int)'key'; // $result is 0
So $$varvar['key'] = 10 is functionally equivalent to:
Code: Select all
$varvar = 'target';
$phpTmp = $varvar[0]; // $phpTmp is 't'
$$phpTmp = 10;
So if you ever want to obfuscate some code....
