Doc #52576 [ReO->Bgs]: Variable variables can create invalid variables.

From: Date: Fri, 13 Aug 2010 04:58:45 +0000
Subject: Doc #52576 [ReO->Bgs]: Variable variables can create invalid variables.
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-4852@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=52576&edit=1 ID: 52576 Updated by: aharvey@php.net Reported by: rquadling@php.net Summary: Variable variables can create invalid variables. -Status: Re-Opened +Status: Bogus Type: Documentation Problem Package: Documentation problem Operating System: Windows XP SP3 PHP Version: 5.3.3 Block user comment: N New Comment: I don't see the issue. That page is pretty clearly talking about variable names in terms of literals, and that is the range of characters that can be used there. The fact that you can circumvent that by going through variable variables or $GLOBALS isn't really relevant. Previous Comments: ------------------------------------------------------------------------ [2010-08-11 13:02:26] rquadling@php.net If this is bogus in terms of the engine, then it is not bogus as a documentation problem. The documentation at http://docs.php.net/manual/en/language.variables.basics.php says that the following : "Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'" Clearly, [ and ] are NOT letters, numbers or underscores. Nor are any of the following characters ',.-+#*#+\ The comment was added 10 years ago (http://svn.php.net/viewvc/phpdoc/en/trunk/language/variables.xml?r1=16980&r2=22177), so in that time something changed. Using the ${$x} construct, you can create a variable of all 256 ASCII characters. <?php // Show all errors. error_reporting(-1); ini_set('display_errors', 1); // Initialize $ord = 0; $char = Null; $before = 0; $before = count($GLOBALS); foreach(range(0, 255) as $ord) { $char = chr($ord); ${$char} = $ord; } echo 'Created ', (count($GLOBALS) - $before), ' variables.', PHP_EOL; ?> outputs ... Created 256 variables. From my testing of PHP3.0.11 through to the latest V5.3.4-dev, the output is the same. A variable can start with anything if using the ${$a} mechanism. ------------------------------------------------------------------------ [2010-08-10 19:46:09] johannes@php.net Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php Variable names may contain any character. ${',.-+#*#+\\'} = 42; This is expected. ------------------------------------------------------------------------ [2010-08-10 18:21:13] rquadling@php.net Description: ------------ It seems you can create a variable in $GLOBALS that is not accessible as a normal variable. I found this because I wanted to use variable variables to populate a nested array. Jim Lucas, in http://news.php.net/php.general/307392, comments that the use of eval() may be appropriate in the case. That aside, the entry that is created in $GLOBALS doesn't follow the rules for variable naming in http://docs.php.net/manual/en/language.variables.basics.php, namely that '[' and ']' are not valid variable names. I think this should have t least produced an E_WARNING. So, with all of that, I'm not sure if this is a bug or a documentation problem. I certainly think it is an edge case. Regards, Richard Quadling. Test script: --------------- <?php // Show all errors. error_reporting(-1); ini_set('display_errors', 1); // Expectation was to be able to create a deep array using variable variables. $a = 'b[1][2][3]'; $$a = 'Inaccessible?'; print_r($b); // Hide superglobals unset($_POST); unset($_GET); unset($_SESSION); unset($_FILES); unset($_COOKIE); unset($_SERVER); unset($argv); unset($argc); // Reveals inaccessible variable. var_dump($GLOBALS); Expected result: ---------------- Array ( [1] => Array ( [2] => Array ( [3] => Inaccessible? ) ) ) array(3) { ["GLOBALS"]=> *RECURSION* ["a"]=> string(10) "b[1][2][3]" ["b"]=> array(1) { [1]=> array(1) { [2]=> array(1) { [3]=> string(13) "Inaccessible?" } } } } Actual result: -------------- Notice: Undefined variable: b in - on line 5 array(4) { ["GLOBALS"]=> *RECURSION* ["a"]=> string(10) "b[1][2][3]" ["b[1][2][3]"]=> string(13) "Inaccessible?" ["php_errormsg"]=> string(21) "Undefined variable: b" } ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=52576&edit=1

« previous php.doc.bugs (#4852) next »