php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #55493 Superglobal variable variables with ${expression} in non-global scope
Submitted: 2011-08-23 14:14 UTC Modified: 2011-09-14 13:20 UTC
Votes:3
Avg. Score:4.0 ± 1.4
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:0 (0.0%)
From: vovan-ve at yandex dot ru Assigned: dmitry (profile)
Status: Wont fix Package: Variables related
PHP Version: 5.3.7 OS: Windows XP SP3
Private report: No CVE-ID: None
 [2011-08-23 14:14 UTC] vovan-ve at yandex dot ru
Description:
------------
ONLY Superglobal variable variables does not work ONLY in non-global
scope and ONLY with non-constant expression. See test script.

I found Req 38527, but it does not describe the problem properly and
due to misunderstanding it has status Feature Request instead of Bug
(and also it is too old).

Test script:
---------------
// in global scope everything is right
$name = '_SERVER';
var_dump(
    isset(${'_SERVER'}),
    isset($$name),
    isset(${$name}),
    isset(${'_SER' . 'VER'}),
    isset(${'na' . 'me'})
);
echo PHP_EOL;

// but outside of global scope there is a trouble
function f() {
    $name = '_SERVER';
    var_dump(
        isset(${'_SERVER'}),
        isset($$name),
        isset(${$name}),
        isset(${'_SER' . 'VER'}),
        isset(${'na' . 'me'})
    );
}
f();

Expected result:
----------------
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

Actual result:
--------------
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

bool(true)
bool(false)
bool(false)
bool(false)
bool(true)

Patches

bug55493.patch (last revision 2011-08-24 12:48 UTC by laruence@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-08-23 16:22 UTC] laruence@php.net
when fetching a variable, the target symbol table is decided in compiling time,  
for the script above,  in compiling time, only const string "_SERVER" can be 
took consider as a SUPERVAR and assign the global symbol table as 
target_symbol_table.

the others `varname` only can be see in execution time, so Zend VM think it 
should be fetched from a local symbol table.

and the 'local symbol table' for the global scope statement is actual 'global 
symbol table', therefor it works 'as expected'.
 [2011-08-23 16:49 UTC] laruence@php.net
-Status: Open +Status: Wont fix
 [2011-08-23 16:49 UTC] laruence@php.net
As I said, this is a limitation of PHP design, so mark as won't fix. 
Thank you for your interest in PHP.
 [2011-08-23 18:16 UTC] kalle@php.net
-Status: Wont fix +Status: Assigned -Type: Bug +Type: Feature/Change Request -Assigned To: +Assigned To: dmitry
 [2011-08-23 18:16 UTC] kalle@php.net
This still seems a little strange that we cannot pick the correct symbol table at compile time, all it should need would be a check to see if the compiled value is matching one thats a super global.

I remember to have encountered something similar a while back, which I'm not sure if I reported or not, but def. something we should look into at some point.

Dmitry, can you clarify this?
 [2011-08-24 04:11 UTC] laruence@php.net
sure, it can be fixed by decide target symbol table again in the execution time 
for not const OPs, 

but I don't think this is really necessary . :)
 [2011-08-24 10:21 UTC] vovan-ve at yandex dot ru
When I tried to obfuscate a part of code I was surprised by this strange behariour. Of course, current implementation is correct on the one hand. But on the other hand the situation looks funny: this way is allowad, and this too, but this is not.
 [2011-08-24 12:48 UTC] laruence@php.net
The following patch has been added/updated:

Patch Name: bug55493.patch
Revision:   1314190137
URL:        https://bugs.php.net/patch-display.php?bug=55493&patch=bug55493.patch&revision=1314190137
 [2011-08-24 12:50 UTC] laruence@php.net
In this case, I make a patch for this, and the test result can be found on: 
http://pastebin.com/6pTuLEer
 [2011-08-24 13:04 UTC] dmitry@php.net
ZE decides if a variable have to be fetched from the global scope at compile time checking predefined list of super-global variables.

The variable fetching by name (e.g. $$name) is always done from local scope.

Of course it's possible to extend executor to check for list of super-global variables at run-time, but it'll introduce significant slowdown for each fetch by name. I really don't like it.
 [2011-08-24 13:54 UTC] laruence@php.net
+1 for dmitry
 [2011-08-24 14:00 UTC] vovan-ve at yandex dot ru
But what about SUPERglobal? In fact they are almost superglobal :)
 [2011-08-24 14:34 UTC] vovan-ve at yandex dot ru
Programmers, who use variable variable, dooms themself to slowdown performance at any way due to calculation of the expressions. They won't see the difference, I think.
 [2011-08-26 23:09 UTC] johannes@php.net
Mind that even when when this special case is treated it still won't work with get_defined_vars() and others. I think the current behavior can be documented in the clearest way giving the least confusion ... so I would not implement it.
 [2011-09-14 13:20 UTC] dmitry@php.net
-Status: Assigned +Status: Wont fix
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC