# [RFC] [PHP 6] Uniform Variable Syntax

- Thread: https://externals.io/message/74793
- Original archive: https://news-web.php.net/php.internals/74793
- Started by Nikita Popov on 2014-06-09T13:33:00+00:00
- Messages: 18
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #74793 — Nikita Popov — 2014-06-09T13:33:00+00:00

URL: https://externals.io/message/74793#74793

Hi internals!

I have created a proposal for a more consistent and complete variable
syntax for PHP 6:

    https://wiki.php.net/rfc/uniform_variable_syntax

The RFC is targeted at PHP 6 because it breaks compatibility for some
rarely used variable-variable constructs.

Thanks,
Nikita

---

## #74796 — Andrea Faulds — 2014-06-09T13:45:41+00:00

URL: https://externals.io/message/74793#74796 · In reply to: #74793

> I have created a proposal for a more consistent and complete variable
> syntax for PHP 6:
> 
>    https://wiki.php.net/rfc/uniform_variable_syntax
> 
> The RFC is targeted at PHP 6 because it breaks compatibility for some
> rarely used variable-variable constructs.

I love this proposal! The behaviour of $$ is non-intuitive at present and has bitten me more than once, and the weird behaviour of :: has also caused me problems. In particular, my miniature web framework didn’t work properly due to this line:

    self::$views[$path]();

It’s easy to fix ($x = self::$views[$path]; $x();) but the fact that didn’t work has bothered me immensely for two years. It seems to me like the RFC would fix this. Would it? If so, you are my hero.

On a somewhat more serious note, do we have any idea of how much code this would break? Is the current behaviour widely relied-upon?

--
Andrea Faulds
http://ajf.me/

---

## #74799 — Nikita Popov — 2014-06-09T14:12:45+00:00

URL: https://externals.io/message/74793#74799 · In reply to: #74796

>
> 
>
> > […]
>
> I love this proposal! The behaviour of $$ is non-intuitive at present and
> has bitten me more than once, and the weird behaviour of :: has also caused
> me problems. In particular, my miniature web framework didn’t work properly
> due to this line:
>
>     self::$views[$path]();
>
> It’s easy to fix ($x = self::$views[$path]; $x();) but the fact that
> didn’t work has bothered me immensely for two years. It seems to me like
> the RFC would fix this. Would it? If so, you are my hero.
>

Yes, it would ;)


> On a somewhat more serious note, do we have any idea of how much code this
> would break? Is the current behaviour widely relied-upon?
>

Quoting
https://wiki.php.net/rfc/uniform_variable_syntax#backward_incompatible_changes
:

> An analysis of the Zend Framework and Symfony projects
> (including standard dependencies) showed that only a single
> occurrence of $loader[0]::$loader[1]($className) in the Doctrine
> class loader will be affected by this change.

So I think that this will not break much code. It is also easy to detect
and fix. (I am using this script to find potential problems:
https://gist.github.com/nikic/ffd019ef78b72934c7cc)

Nikita

---

## #74801 — Andrea Faulds — 2014-06-09T14:16:28+00:00

URL: https://externals.io/message/74793#74801 · In reply to: #74799

> So I think that this will not break much code. It is also easy to detect
> and fix. (I am using this script to find potential problems:
> https://gist.github.com/nikic/ffd019ef78b72934c7cc)

I like that you have a script. Myself, I’d like to see more of these. Since your PhpParser exists, if we make some major syntax change in PHP6, it might be possible to write a tool that would (semi-)automatically re-write code, similar to what Python’s 2to3 tool does.

--
Andrea Faulds
http://ajf.me/

---

## #74803 — Florian Anderiasch — 2014-06-09T15:02:37+00:00

URL: https://externals.io/message/74793#74803 · In reply to: #74793

>     https://wiki.php.net/rfc/uniform_variable_syntax
> 
> The RFC is targeted at PHP 6 because it breaks compatibility for some
> rarely used variable-variable constructs.

I am all for consistency, but if I look at this:

>Example of expressions those meaning changes:

>                     // old meaning        // new meaning
> $$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
> Foo::$bar['baz']()  Foo::{$bar['baz']}()  (Foo::$bar)['baz']()
> $foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()

Those last 2 lines (old meaning) are exactly as I would have read them
without thinking. So.. either I just got used to some kind of subliminal
rule over all these years or I'm missing something. They're not variable
variables, either.

Somewhere in the proposal you write "It follows normal left-to-right
semantic". This sounds very good in theory, but right now it feels a
little unintuitive.

Greetings,
Florian

---

## #74804 — Rowan Collins — 2014-06-09T16:06:40+00:00

URL: https://externals.io/message/74793#74804 · In reply to: #74803

Florian Anderiasch wrote (on 09/06/2014):
> > […]
> Those last 2 lines (old meaning) are exactly as I would have read them
> without thinking. So.. either I just got used to some kind of subliminal
> rule over all these years or I'm missing something.

I think it's somewhat subjective; it wouldn't have occurred to me that 
$foo->$bar['baz']() would evaluate $bar['baz'] rather than $foo->$bar. 
The advantage of the proposed behaviour is that it can be easily 
explained to *new* users of the language, as it's internally consistent, 
which appears not to be true of the old - an example in the RFC being 
|Foo::$bar[1][2][3] vs ||Foo::$bar[1][2][3]()|

The ability for any length of expression to be evaluated consistently 
and according to an easily-explained logic makes this RFC a massive win 
for me unless anyone can come up with a case it changes that would 
already be in common use.

If this had happened sooner, we wouldn't have needed separate RFCs for 
some_function()['array_key'] and (new Some_Class)->someMethod()

> They're not variable variables, either.

Technically, $foo->$bar is a "dynamic property access" (resolve the 
contents of $bar as a string, access that property), but it has a lot in 
common with what are commonly thought of as "variable variables"; if you 
have a class with property 'prop1', "normal" access would be via 
$foo->prop1, just as "normal" access to a variable would be $var1, not 
$$foo.

There are slightly more cases where dynamic property access makes sense 
than plain variable variables (which can nearly always be replaced with 
an associative array), but exotic combinations like the ones affected 
here seem unlikely to be commonplace.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #74805 — Adam Harvey — 2014-06-09T16:27:04+00:00

URL: https://externals.io/message/74793#74805 · In reply to: #74793

> I have created a proposal for a more consistent and complete variable
> syntax for PHP 6:
>
>     https://wiki.php.net/rfc/uniform_variable_syntax
>
> The RFC is targeted at PHP 6 because it breaks compatibility for some
> rarely used variable-variable constructs.

I like it.

A Monday morning, pre-caffeine-kicking-in thought (so it may not be
very worthwhile): can we detect the situations that would change with
this patch applied within the current parser? If we did go ahead with
this for PHP 5++, then we could potentially add `E_STRICT` warnings in
PHP 5.7 notifying users that the behaviour will change in the next
major version.

Adam

---

## #74809 — Michael Wallner — 2014-06-10T06:01:30+00:00

URL: https://externals.io/message/74793#74809 · In reply to: #74793

> Hi internals!
> 
> I have created a proposal for a more consistent and complete variable
> syntax for PHP 6:
> 
>    https://wiki.php.net/rfc/uniform_variable_syntax

Thank you!

---

## #74810 — Julien Pauli — 2014-06-10T08:06:47+00:00

URL: https://externals.io/message/74793#74810 · In reply to: #74793

> Hi internals!
>
> I have created a proposal for a more consistent and complete variable
> syntax for PHP 6:
>
>     https://wiki.php.net/rfc/uniform_variable_syntax
>
> The RFC is targeted at PHP 6 because it breaks compatibility for some
> rarely used variable-variable constructs.
>
> Thanks,
> Nikita

Nice proposal :-)

Julien

---

## #74813 — Pierre Joye — 2014-06-10T10:58:08+00:00

URL: https://externals.io/message/74793#74813 · In reply to: #74793

hi Nikita,


> Hi internals!
>
> I have created a proposal for a more consistent and complete variable
> syntax for PHP 6:
>
>     https://wiki.php.net/rfc/uniform_variable_syntax
>
> The RFC is targeted at PHP 6 because it breaks compatibility for some
> rarely used variable-variable constructs.

Very good RFC. Long due and php6 is really the right time to do it. As
you said it should have a minimal impact on existing code.

If accepted, it would be a good thing to add notices in 5.6 as well,
if it does not impact performance too much.

Cheers,
-- 
Pierre

@pierrejoye | http://www.libgd.org

---

## #74814 — Rowan Collins — 2014-06-10T11:38:11+00:00

URL: https://externals.io/message/74793#74814 · In reply to: #74804

Rowan Collins wrote (on 09/06/2014):
> The advantage of the proposed behaviour is that it can be easily 
> explained to *new* users of the language, as it's internally 
> consistent, which appears not to be true of the old - an example in 
> the RFC being |Foo::$bar[1][2][3] vs ||Foo::$bar[1][2][3]()| 

A simpler example of the current logic's inconsistencies:

$foo = 'foo';
$bar->$foo = array();
$bar->$foo[0] = 42;
// $bar now has an array on ->foo, and an integer on ->f

http://3v4l.org/pImS3

Not only does this not feel consistent in itself, it's different if you 
do the same thing with an object:

$foo = 'foo';
$bar->$foo = new stdClass;
$bar->$foo->x = 42;
// $bar now has a single property ->foo, which is an object with 
property ->x

http://3v4l.org/DUaJj

Other than "it's always worked this way", I can't think of a good 
justification for this difference.

-- 
Rowan Collins
[IMSoP]

---

## #74834 — Stas Malyshev — 2014-06-10T23:09:10+00:00

URL: https://externals.io/message/74793#74834 · In reply to: #74813

Hi!

> If accepted, it would be a good thing to add notices in 5.6 as well,
> if it does not impact performance too much.

I wouldn't be that fast with it, since notices are very expensive
(compared to regular opcodes), and disabling them via error_level does
nothing to mitigate that effect, and may easily lead to breakage in
systems which have custom handlers - like unit tests, monitoring, etc.
When we're going to 6, it's good to break things we want to change. When
we're talking about 5.6, less disruption to existing working code the
better.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #75166 — Nikita Popov — 2014-07-02T15:51:22+00:00

URL: https://externals.io/message/74793#75166 · In reply to: #74793

> Hi internals!
>
> I have created a proposal for a more consistent and complete variable
> syntax for PHP 6:
>
>     https://wiki.php.net/rfc/uniform_variable_syntax
>
> The RFC is targeted at PHP 6 because it breaks compatibility for some
> rarely used variable-variable constructs.
>

Any more feedback on this? Otherwise I'll start the vote sometime soon :)

Nikita

---

## #75167 — Lazare Inepologlou — 2014-07-02T16:04:42+00:00

URL: https://externals.io/message/74793#75167 · In reply to: #75166

2014-07-02 17:51 GMT+02:00 Nikita Popov <nikita.ppv@gmail.com>:

> 
>
> > […]
>
> Any more feedback on this? Otherwise I'll start the vote sometime soon :)
>
>
Yes, in the RFC, you mention that this will be possible:

($obj->closure)()

While this is very welcome, I was wandering if we could skip the extra
parenthesis, like this:

$obj->closure()

Likewise, this would also be nice:

new ClassName->foo()



Thanks,

Lazare INEPOLOGLOU
Ingénieur Logiciel

---

## #75168 — Andrea Faulds — 2014-07-02T16:09:49+00:00

URL: https://externals.io/message/74793#75168 · In reply to: #75167

> Yes, in the RFC, you mention that this will be possible:
> 
> ($obj->closure)()
> 
> While this is very welcome, I was wandering if we could skip the extra
> parenthesis, like this:
> 
> $obj->closure()

Sadly, it wouldn’t be possible as the two are very different. Properties and methods occupy completely different namespaces, and while methods are case-insentivie, properties are case-sensitive! ($obj->closure)() gets a property then calls it, while $obj->closure() calls a method.

Perhaps this might change in future, but the RFC doesn’t propose that.
--
Andrea Faulds
http://ajf.me/

---

## #75169 — Nikita Popov — 2014-07-02T16:25:25+00:00

URL: https://externals.io/message/74793#75169 · In reply to: #75167

On Wed, Jul 2, 2014 at 6:04 PM, Lazare Inepologlou <linepogl@gmail.com>
wrote:

>
> 2014-07-02 17:51 GMT+02:00 Nikita Popov <nikita.ppv@gmail.com>:
>
> 
> > […]
> Yes, in the RFC, you mention that this will be possible:
>
> ($obj->closure)()
>
> While this is very welcome, I was wandering if we could skip the extra
> parenthesis, like this:
>
> $obj->closure()
>

We could skip the extra parenthesis, but that would require changing the
meaning of method calls. This discussion turns up every now and then, one
of the more recent ones being http://markmail.org/message/3zi53txadno6xrqa.
A key problem was always that supporting this would break BC. However that
BC break may be acceptable for PHP 6, so the it might be worthwhile to
reconsider the previous decisions regarding this issue.

However this is not related to variable syntax (it is a question of method
lookup semantics), so I would suggest opening a new discussion thread for
this (and/or write an RFC for it).


> Likewise, this would also be nice:
>
> new ClassName->foo()
>

This is problematic because the following would be ambiguous:

    new $className->foo()
    // could be (_current_ behavior)
    new ($className->foo)()
    // or
    (new $className)->foo()

Of course we could resolve the ambiguity (towards the _latter_
interpretation) or special-case the plain-classname case. Both options do
not seem very appealing to me. Imho it's better to keep the explicit syntax.

Nikita

---

## #75171 — Rowan Lewis — 2014-07-02T17:58:44+00:00

URL: https://externals.io/message/74793#75171 · In reply to: #75169

How would you create a new callable object and then invoke it? Since
'nested' () is now supported:

    new MagicInvoke()();

Could be the same as:

    (new MagicInvoke())();




> On Wed, Jul 2, 2014 at 6:04 PM, Lazare Inepologlou <linepogl@gmail.com>
> wrote:
>
> > […]
> wrote:
> > […]
> :)
> > […]
>
> We could skip the extra parenthesis, but that would require changing the
> meaning of method calls. This discussion turns up every now and then, one
> of the more recent ones being http://markmail.org/message/3zi53txadno6xrqa
> .
> A key problem was always that supporting this would break BC. However that
> BC break may be acceptable for PHP 6, so the it might be worthwhile to
> reconsider the previous decisions regarding this issue.
>
> However this is not related to variable syntax (it is a question of method
> lookup semantics), so I would suggest opening a new discussion thread for
> this (and/or write an RFC for it).
>
>
> > […]
>
> This is problematic because the following would be ambiguous:
>
>     new $className->foo()
>     // could be (_current_ behavior)
>     new ($className->foo)()
>     // or
>     (new $className)->foo()
>
> Of course we could resolve the ambiguity (towards the _latter_
> interpretation) or special-case the plain-classname case. Both options do
> not seem very appealing to me. Imho it's better to keep the explicit
> syntax.
>
> Nikita

---

## #75173 — Stas Malyshev — 2014-07-02T18:20:18+00:00

URL: https://externals.io/message/74793#75173 · In reply to: #75167

Hi!

> While this is very welcome, I was wandering if we could skip the extra
> parenthesis, like this:
> 
> $obj->closure()

The would mean uniting the property and method namespaces on an object,
which has pretty big implications and may lead to huge BC issues. I'd
rather not go there, it'd require serious change of the whole object model.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
