Question about `global` variable declaration

  107274
September 21, 2019 09:55 webdevxp.com@gmail.com (Kosit Supanyo)
Hi Internals

I'm working on my new proposals and I've found weirdness of global variable
declaration in zend_language_parser.y.

global_var:
    simple_variable
        { $$ = zend_ast_create(ZEND_AST_GLOBAL,
zend_ast_create(ZEND_AST_VAR, $1)); }
;

Above grammer allows something like this...

global $$x;
global $$$y;
global $$$$z;
global ${'abc'};
global $$$$$$$$$${random_int(0, PHP_INT_MAX)};

What's the propose of allowing this? And is there anyone out there knowing
and using it? If not, should this be changed to allow only T_VARIABLE to
make it consistent with `static` variable declaration?

Regards
  107275
September 21, 2019 10:23 Danack@basereality.com (Dan Ackroyd)
Hi Kosit,

On Sat, 21 Sep 2019 at 10:56, Kosit Supanyo com@gmail.com> wrote:
> > global $$x; > global $$$y; > global $$$$z; > global ${'abc'}; > global $$$$$$$$$${random_int(0, PHP_INT_MAX)};
I have found the form `global ${'abc'};` useful in the past to work around the limits on what PHP can parse as variable names, to allow naming global settings to match how I like to write them in config files e.g. 'image.upload.retry_attempts'. I would be very surprised if there was no codebase in existence that didn't use the other forms, for better or worse.
> If not, should this be changed to ...
For changes like this, the conversation almost certainly needs to start by stating a clear problem something is causing, and then lead on to why doing a suggested solution is the right thing to do. Although this might be a small inconsistency in the language, by itself, I can't see it causing much harm, except maybe for performance optimisation as trying to analyze what variables are being used in the code is hard. cheers Dan Ack
  107276
September 21, 2019 10:51 nikita.ppv@gmail.com (Nikita Popov)
On Sat, Sep 21, 2019 at 11:56 AM Kosit Supanyo com@gmail.com>
wrote:

> Hi Internals > > I'm working on my new proposals and I've found weirdness of global variable > declaration in zend_language_parser.y. > > global_var: > simple_variable > { $$ = zend_ast_create(ZEND_AST_GLOBAL, > zend_ast_create(ZEND_AST_VAR, $1)); } > ; > > Above grammer allows something like this... > > global $$x; > global $$$y; > global $$$$z; > global ${'abc'}; > global $$$$$$$$$${random_int(0, PHP_INT_MAX)}; > > What's the propose of allowing this? And is there anyone out there knowing > and using it? If not, should this be changed to allow only T_VARIABLE to > make it consistent with `static` variable declaration? > > Regards >
Some grep results: sources/adodb/adodb-php/session/adodb-session.php 676: global $$var; 697: global $$var; sources/adodb/adodb-php/session/adodb-session2.php 719: global $$var; 740: global $$var; sources/adodb/adodb-php/session/old/adodb-cryptsession.php 189: global $$var; sources/adodb/adodb-php/session/old/adodb-session.php 300: global $$var; sources/adodb/adodb-php/session/old/adodb-session-clob.php 269: global $$var; sources/wp-cli/wp-cli/php/WP_CLI/Runner.php 1177: global ${$key}; sources/apache/log4php/src/main/php/pattern/LoggerPatternConverterSuperglobal.php 71: global ${$this->name}; We could deprecate this in favor of $GLOBALS, though as Dan said, the motivation is not quite clear right now. Nikita
  107277
September 21, 2019 10:58 webdevxp.com@gmail.com (Kosit Supanyo)
Hi Dan and Internals

Sorry  Dan, I forgot to include @Internals in previous reply so let me
resend this again.

Thank you for your reply. I see, but in that case it can be done with
`$GLOBALS['abc']` right? So I don't see any benefits of allowing those
forms, they're just another inconsistency that should not exist from the
beginning. Yes, it does no harms but if nobody is really using it at all,
is it good to remove this inconsistency? Or to make it really useful, why
not just allow assignment like:

global ${'abc'} = $someValue;

Just my 2 cents.

Regards

On Sat, Sep 21, 2019 at 5:52 PM Nikita Popov ppv@gmail.com> wrote:

> On Sat, Sep 21, 2019 at 11:56 AM Kosit Supanyo com@gmail.com> > wrote: > >> Hi Internals >> >> I'm working on my new proposals and I've found weirdness of global >> variable >> declaration in zend_language_parser.y. >> >> global_var: >> simple_variable >> { $$ = zend_ast_create(ZEND_AST_GLOBAL, >> zend_ast_create(ZEND_AST_VAR, $1)); } >> ; >> >> Above grammer allows something like this... >> >> global $$x; >> global $$$y; >> global $$$$z; >> global ${'abc'}; >> global $$$$$$$$$${random_int(0, PHP_INT_MAX)}; >> >> What's the propose of allowing this? And is there anyone out there knowing >> and using it? If not, should this be changed to allow only T_VARIABLE to >> make it consistent with `static` variable declaration? >> >> Regards >> > > Some grep results: > > sources/adodb/adodb-php/session/adodb-session.php > 676: global $$var; > 697: global $$var; > > sources/adodb/adodb-php/session/adodb-session2.php > 719: global $$var; > 740: global $$var; > > sources/adodb/adodb-php/session/old/adodb-cryptsession.php > 189: global $$var; > > sources/adodb/adodb-php/session/old/adodb-session.php > 300: global $$var; > > sources/adodb/adodb-php/session/old/adodb-session-clob.php > 269: global $$var; > > sources/wp-cli/wp-cli/php/WP_CLI/Runner.php > 1177: global ${$key}; > > > sources/apache/log4php/src/main/php/pattern/LoggerPatternConverterSuperglobal.php > 71: global ${$this->name}; > > We could deprecate this in favor of $GLOBALS, though as Dan said, the > motivation is not quite clear right now. > > Nikita >
  107279
September 21, 2019 11:24 nikita.ppv@gmail.com (Nikita Popov)
On Sat, Sep 21, 2019 at 12:58 PM Kosit Supanyo com@gmail.com>
wrote:

> Hi Dan and Internals > > Sorry Dan, I forgot to include @Internals in previous reply so let me > resend this again. > > Thank you for your reply. I see, but in that case it can be done with > `$GLOBALS['abc']` right? So I don't see any benefits of allowing those > forms, they're just another inconsistency that should not exist from the > beginning. Yes, it does no harms but if nobody is really using it at all, > is it good to remove this inconsistency? Or to make it really useful, why > not just allow assignment like: > > global ${'abc'} = $someValue; > > Just my 2 cents. > > Regards >
global $x; is a shorthand for $x =& $GLOBALS['x']; global ${$x}; is a shorthand for ${$x} =& $GLOBALS[$x]; I don't think this syntax is inconsistent so long as PHP supports the syntax ${$x} for variables in general. The idea of a "global ${'abc'} = $someValue;" syntax doesn't seem to have a relation to the ${} form in particular. A simple "global $var = $someValue" is currently not supported either. That's because "global $var" simply imports a global variable into the local scope. You would instead write this as "global $var; $var = $someValue;". Nikita
> On Sat, Sep 21, 2019 at 5:52 PM Nikita Popov ppv@gmail.com> wrote: > >> On Sat, Sep 21, 2019 at 11:56 AM Kosit Supanyo com@gmail.com> >> wrote: >> >>> Hi Internals >>> >>> I'm working on my new proposals and I've found weirdness of global >>> variable >>> declaration in zend_language_parser.y. >>> >>> global_var: >>> simple_variable >>> { $$ = zend_ast_create(ZEND_AST_GLOBAL, >>> zend_ast_create(ZEND_AST_VAR, $1)); } >>> ; >>> >>> Above grammer allows something like this... >>> >>> global $$x; >>> global $$$y; >>> global $$$$z; >>> global ${'abc'}; >>> global $$$$$$$$$${random_int(0, PHP_INT_MAX)}; >>> >>> What's the propose of allowing this? And is there anyone out there >>> knowing >>> and using it? If not, should this be changed to allow only T_VARIABLE to >>> make it consistent with `static` variable declaration? >>> >>> Regards >>> >> >> Some grep results: >> >> sources/adodb/adodb-php/session/adodb-session.php >> 676: global $$var; >> 697: global $$var; >> >> sources/adodb/adodb-php/session/adodb-session2.php >> 719: global $$var; >> 740: global $$var; >> >> sources/adodb/adodb-php/session/old/adodb-cryptsession.php >> 189: global $$var; >> >> sources/adodb/adodb-php/session/old/adodb-session.php >> 300: global $$var; >> >> sources/adodb/adodb-php/session/old/adodb-session-clob.php >> 269: global $$var; >> >> sources/wp-cli/wp-cli/php/WP_CLI/Runner.php >> 1177: global ${$key}; >> >> >> sources/apache/log4php/src/main/php/pattern/LoggerPatternConverterSuperglobal.php >> 71: global ${$this->name}; >> >> We could deprecate this in favor of $GLOBALS, though as Dan said, the >> motivation is not quite clear right now. >> >> Nikita >> >
  107280
September 21, 2019 12:09 webdevxp.com@gmail.com (Kosit Supanyo)
I understand your point but inconsistency in my sense is syntactical By
comparing to other declaration syntax like `var`, `static`, 'public` an
others. They allow only T_VARIABLE but `global` is different. And there's
another way to archive the same goal through `$GLOBALS`, that's why I see
it as inconsistency.

P.S. I wrote this not because I want to convince you to make any change but
just to explain my point.

Cheers

On Sat, Sep 21, 2019 at 6:24 PM Nikita Popov ppv@gmail.com> wrote:

> On Sat, Sep 21, 2019 at 12:58 PM Kosit Supanyo com@gmail.com> > wrote: > >> Hi Dan and Internals >> >> Sorry Dan, I forgot to include @Internals in previous reply so let me >> resend this again. >> >> Thank you for your reply. I see, but in that case it can be done with >> `$GLOBALS['abc']` right? So I don't see any benefits of allowing those >> forms, they're just another inconsistency that should not exist from the >> beginning. Yes, it does no harms but if nobody is really using it at all, >> is it good to remove this inconsistency? Or to make it really useful, why >> not just allow assignment like: >> >> global ${'abc'} = $someValue; >> >> Just my 2 cents. >> >> Regards >> > > global $x; is a shorthand for $x =& $GLOBALS['x']; > global ${$x}; is a shorthand for ${$x} =& $GLOBALS[$x]; > > I don't think this syntax is inconsistent so long as PHP supports the > syntax ${$x} for variables in general. > > The idea of a "global ${'abc'} = $someValue;" syntax doesn't seem to have > a relation to the ${} form in particular. A simple "global $var = > $someValue" is currently not supported either. That's because "global $var" > simply imports a global variable into the local scope. You would instead > write this as "global $var; $var = $someValue;". > > Nikita > > >> On Sat, Sep 21, 2019 at 5:52 PM Nikita Popov ppv@gmail.com> >> wrote: >> >>> On Sat, Sep 21, 2019 at 11:56 AM Kosit Supanyo com@gmail.com> >>> wrote: >>> >>>> Hi Internals >>>> >>>> I'm working on my new proposals and I've found weirdness of global >>>> variable >>>> declaration in zend_language_parser.y. >>>> >>>> global_var: >>>> simple_variable >>>> { $$ = zend_ast_create(ZEND_AST_GLOBAL, >>>> zend_ast_create(ZEND_AST_VAR, $1)); } >>>> ; >>>> >>>> Above grammer allows something like this... >>>> >>>> global $$x; >>>> global $$$y; >>>> global $$$$z; >>>> global ${'abc'}; >>>> global $$$$$$$$$${random_int(0, PHP_INT_MAX)}; >>>> >>>> What's the propose of allowing this? And is there anyone out there >>>> knowing >>>> and using it? If not, should this be changed to allow only T_VARIABLE to >>>> make it consistent with `static` variable declaration? >>>> >>>> Regards >>>> >>> >>> Some grep results: >>> >>> sources/adodb/adodb-php/session/adodb-session.php >>> 676: global $$var; >>> 697: global $$var; >>> >>> sources/adodb/adodb-php/session/adodb-session2.php >>> 719: global $$var; >>> 740: global $$var; >>> >>> sources/adodb/adodb-php/session/old/adodb-cryptsession.php >>> 189: global $$var; >>> >>> sources/adodb/adodb-php/session/old/adodb-session.php >>> 300: global $$var; >>> >>> sources/adodb/adodb-php/session/old/adodb-session-clob.php >>> 269: global $$var; >>> >>> sources/wp-cli/wp-cli/php/WP_CLI/Runner.php >>> 1177: global ${$key}; >>> >>> >>> sources/apache/log4php/src/main/php/pattern/LoggerPatternConverterSuperglobal.php >>> 71: global ${$this->name}; >>> >>> We could deprecate this in favor of $GLOBALS, though as Dan said, the >>> motivation is not quite clear right now. >>> >>> Nikita >>> >>
  107281
September 21, 2019 14:25 zeev@php.net (Zeev Suraski)
On Sat, Sep 21, 2019 at 3:09 PM Kosit Supanyo com@gmail.com>
wrote:

> I understand your point but inconsistency in my sense is syntactical By > comparing to other declaration syntax like `var`, `static`, 'public` an > others. They allow only T_VARIABLE but `global` is different. And there's > another way to archive the same goal through `$GLOBALS`, that's why I see > it as inconsistency. >
Even though we're dealing with archeology here - this really isn't an inconsistency but intended behavior. Unlike var, public, static and others - 'global' is not a declaration of class structure, but a way to access global variables. In the same way it sometimes makes sense to access variables indirectly ($$foo), it may sometimes make sense to access global variables indirectly (global $$foo). It allows for both creation and access of global variables. It doesn't sound very useful or practical to provide that ability for the creation of dynamic class properties, which is why it's not available for var/public/static/etc. Zeev
  107282
September 21, 2019 15:18 webdevxp.com@gmail.com (Kosit Supanyo)
> > Unlike var, public, static and others - 'global' is not a declaration of > class structure, but a way to access global variables.
I know it is not and I think almost everyone knows that. As I said, I came up with this by comparing to other declarations syntactically not functionally, it is inconsistent in that way. I don't know how many PHP developers out there know `global` can take variable variables but I my guess is, very very little because there's no information about this behavior of `global` in PHP manual https://www.php.net/manual/en/language.variables.scope.php and I'd never seen those forms of `global` in any projects/articles before. Cheers On Sat, Sep 21, 2019 at 9:26 PM Zeev Suraski <zeev@php.net> wrote:
> On Sat, Sep 21, 2019 at 3:09 PM Kosit Supanyo com@gmail.com> > wrote: > >> I understand your point but inconsistency in my sense is syntactical By >> comparing to other declaration syntax like `var`, `static`, 'public` an >> others. They allow only T_VARIABLE but `global` is different. And there's >> another way to archive the same goal through `$GLOBALS`, that's why I see >> it as inconsistency. >> > > Even though we're dealing with archeology here - this really isn't an > inconsistency but intended behavior. > Unlike var, public, static and others - 'global' is not a declaration of > class structure, but a way to access global variables. In the same way it > sometimes makes sense to access variables indirectly ($$foo), it may > sometimes make sense to access global variables indirectly (global $$foo). > It allows for both creation and access of global variables. It doesn't > sound very useful or practical to provide that ability for the creation of > dynamic class properties, which is why it's not available for > var/public/static/etc. > > Zeev >
  107284
September 21, 2019 18:46 zeev@php.net (Zeev Suraski)
On Sat, Sep 21, 2019 at 6:18 PM Kosit Supanyo com@gmail.com>
wrote:

> Unlike var, public, static and others - 'global' is not a declaration of >> class structure, but a way to access global variables. > > > I know it is not and I think almost everyone knows that. As I said, I came > up with this by comparing to other declarations syntactically not > functionally, it is inconsistent in that way. I don't know how many PHP > developers out there know `global` can take variable variables but I my > guess is, very very little because there's no information about this > behavior of `global` in PHP manual > https://www.php.net/manual/en/language.variables.scope.php and I'd never > seen those forms of `global` in any projects/articles before. >
I think you're raising two separate points: 1. The global statement is inconsistent with other similar statements. 2. It's not widely used and we should consider deprecating this behavior. Re: #1 - even though it may look similar, the global statement is fundamentally different from public/private/static and friends. It's not really a declaration - it's like Nikita said is a simple equivalent for writing $foo = &$GLOBALS['foo'] - and as such, is a runtime statement as opposed to a compile-time declaration like the others. So despite the superficial similarities, the differences between the two justify different behavior/allowed syntax. Re: #2 - the fact it's not documented is a fair point - but I'm not sure that in itself is cause for anything other than perhaps adding a quick note in the docs. People familiar with PHP's variable-variables functionality ( https://www.php.net/manual/en/language.variables.variable.php) will not find this behavior as inconsistent or otherwise surprising, I think. It does appear to be mentioned in some places (e.g. the O'Reilly PHP Cookbook, https://www.oreilly.com/library/view/php-cookbook/1565926811/ch06s12.html). I doubt there'll be a big impact if we were to deprecate this behavior - it doesn't appear very mainstream (and there's a simple workaround available through $GLOBALS) - but I don't see any gain to be had either. Zeev