Doc #52576 [ReO->Bgs]: Variable variables can create invalid variables.
| From: | aharvey@php.net | 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