php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #52576 Variable variables can create invalid variables.
Submitted: 2010-08-10 18:21 UTC Modified: 2010-08-13 10:50 UTC
From: rquadling@php.net Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 5.3.3 OS: Windows XP SP3
Private report: No CVE-ID: None
 [2010-08-10 18:21 UTC] 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"
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-08-10 19:46 UTC] johannes@php.net
-Status: Open +Status: Bogus
 [2010-08-10 19:46 UTC] 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-11 13:02 UTC] rquadling@php.net
-Status: Bogus +Status: Re-Opened -Type: Bug +Type: Documentation Problem -Package: Scripting Engine problem +Package: Documentation problem
 [2010-08-11 13:02 UTC] 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-13 06:58 UTC] aharvey@php.net
-Status: Re-Opened +Status: Bogus
 [2010-08-13 06:58 UTC] aharvey@php.net
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.
 [2010-08-13 10:50 UTC] rquadling@php.net
get_defined_vars() also shows the variables whose names don't match the rules 
defined for variable names, so not just using $GLOBALS (though internally this is 
probably the same thing).

I think that the "variable variable" page needs to mention the fact that you can 
create non-standard variables (standard being set on the basic variables page).
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 15:01:30 2024 UTC