[RFC] Fix inconsistent behavior of $this variable

php.internals

Dmitry Stogov

10 years ago
Hi internals, Please review the RFC. It proposes to fix all known inconsistencies related to handling of special $this variable. https://wiki.php.net/rfc/this_var Thanks. Dmitry.

Nikita Popov

10 years ago
On Mon, May 23, 2016 at 10:24 PM, Dmitry Stogov <dmitry@zend.com> wrote:
> Hi internals, > > > Please review the RFC. > > It proposes to fix all known inconsistencies related to handling of > special $this variable. > > > https://wiki.php.net/rfc/this_var > > > Thanks. Dmitry. >
How does this interact with things like extract() or get_defined_vars()? The"static function __call()" case looks like a bug... Shouldn't this just be a compiler error in the first place? Nikita

Dmitry Stogov

10 years ago
good point. I'll update RFC and patch to support extract() and get_defined_vars(). ________________________________ From: Nikita Popov <nikita.ppv@gmail.com> Sent: Monday, May 23, 2016 11:46:35 PM To: Dmitry Stogov Cc: internals; Nikita Popov; Bob Weinand; Xinchen Hui Subject: Re: [PHP-DEV] [RFC] Fix inconsistent behavior of $this variable On Mon, May 23, 2016 at 10:24 PM, Dmitry Stogov <dmitry@zend.com<mailto:dmitry@zend.com>> wrote: Hi internals, Please review the RFC. It proposes to fix all known inconsistencies related to handling of special $this variable. https://wiki.php.net/rfc/this_var Thanks. Dmitry. How does this interact with things like extract() or get_defined_vars()? The"static function __call()" case looks like a bug... Shouldn't this just be a compiler error in the first place? Nikita

James Gilliland

10 years ago
In the section "Disable ability to re-assign $this indirectly through $$" it looks like there is a typo. It only makes sense if you mean $$a instead of $aa.

Laruence

10 years ago
Hey: On Tue, May 24, 2016 at 4:24 AM, Dmitry Stogov <dmitry@zend.com> wrote:
> Hi internals, > > > Please review the RFC. > > It proposes to fix all known inconsistencies related to handling of > special $this variable. >
in section static this, actually, the codes doesn't work in 7.0 neither. it will result in fatal error: PHP Fatal error: Cannot re-assign $this thanks
> > https://wiki.php.net/rfc/this_var > > > Thanks. Dmitry. >
-- Xinchen Hui @Laruence http://www.laruence.com/

Dmitry Stogov

10 years ago
On 05/24/2016 05:29 AM, Xinchen Hui wrote:
> Hey: > > > > On Tue, May 24, 2016 at 4:24 AM, Dmitry Stogov <dmitry@zend.com > <mailto:dmitry@zend.com>> wrote: > > Hi internals, > > > Please review the RFC. > > It proposes to fix all known inconsistencies related to handling > of special $this variable. > > in section static this, actually, the codes doesn't work in 7.0 neither. > > it will result in fatal error: PHP Fatal error: Cannot re-assign $this
Right. Thanks. Fixed. Dmitry.

Jesse Schalken

10 years ago
I'm curious, what is it about $this that makes it special in the first place? Can't it be a normal local variable that happens to already be assigned at the start of a method? On Tue, May 24, 2016 at 6:24 AM, Dmitry Stogov <dmitry@zend.com> wrote:

Dmitry Stogov

10 years ago
On 05/24/2016 08:45 AM, Jesse Schalken wrote:
> I'm curious, what is it about $this that makes it special in the first > place? Can't it be a normal local variable that happens to already be > assigned at the start of a method?
In fact $this is not a regular local variable and it must not be re-assigned. Thank. Dmitry.

Jesse Schalken

10 years ago
On Tue, May 24, 2016 at 5:18 PM, Dmitry Stogov <dmitry@zend.com> wrote:
> In fact $this is not a regular local variable and it must not be > re-assigned. > >
You're just restating the premise for my question. Why is it not a regular local variable? Why must it not be reassigned?

Yasuo Ohgaki

10 years ago
Jesse, On Tue, May 24, 2016 at 4:25 PM, Jesse Schalken <me@jesseschalken.com> wrote:
> On Tue, May 24, 2016 at 5:18 PM, Dmitry Stogov <dmitry@zend.com> wrote: > >> In fact $this is not a regular local variable and it must not be >> re-assigned. >> >> > You're just restating the premise for my question. Why is it not a regular > local variable? Why must it not be reassigned?
$this must be a object you're accessing. If you can change $this, you'll suddenly loose object. PHP 4 treated $this as regular variable and caused lots of problems. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Jesse Schalken

10 years ago
On Tue, May 24, 2016 at 5:54 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Jesse, > > $this must be a object you're accessing. >
Why? I consider it a kind of implied parameter. You can reassign self in Python for example. class MyClass: def foo(self, p1, p2): self = 7 print(self, p1, p2) c = MyClass() c.foo(8, 3); # 7 8 3 I can't think of anything else that allows it, though. If you can change $this, you'll suddenly loose object.
>
That's what tends to happen when you assign a variable.
> PHP 4 treated $this as regular variable and caused lots of problems. >
I'll have to take your word for it. I just thought the language would be simpler with fewer "special" things that don't need to be special.

Zeev Suraski

10 years ago
> -----Original Message----- > From: jesseschalken@gmail.com [mailto:jesseschalken@gmail.com] On > Behalf Of Jesse Schalken > Sent: Tuesday, May 24, 2016 11:42 AM > To: Yasuo Ohgaki <yohgaki@ohgaki.net> > Cc: Dmitry Stogov <dmitry@zend.com>; internals <internals@lists.php.net>; > Nikita Popov <nikic@php.net>; Bob Weinand <bwoebi@php.net>; Xinchen Hui > <laruence@php.net> > Subject: Re: [PHP-DEV] [RFC] Fix inconsistent behavior of $this variable > > On Tue, May 24, 2016 at 5:54 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> > wrote: > > > Jesse, > > > > $this must be a object you're accessing. > > > > Why? I consider it a kind of implied parameter. You can reassign self in Python > for example.
Jesse, You consider it an implied parameter, we considered it to be a representation of the currently scoped object at the language level. Your way is not inherently wrong - but you know that already, as you've demonstrated other languages that allow this. And while it's not wrong, it's also not the semantics we agreed upon for $this in PHP.
> I'll have to take your word for it. I just thought the language would be simpler > with fewer "special" things that don't need to be special.
While we could debate whether it’s more or less special, an implied parameter is also special. So we wouldn't have fewer special things, just different ones. Zeev

Rowan Collins

10 years ago
On 24/05/2016 06:45, Jesse Schalken wrote:
> I'm curious, what is it about $this that makes it special in the first > place? Can't it be a normal local variable that happens to already be > assigned at the start of a method?
There are a few things that take advantage of its specialness, e.g. - binding a closure to an object changes the meaning of $this in a way very different from assigning it into scope with "use($this)" - a method declared static can detect and throw errors on anything referencing $this - when calling parent::foo() from an instance method, the value of $this needs to be set appropriately on the new method; being able to reassign $this could lead to some odd behaviour there Python's approach is certainly valid, and leads to some different useful properties, I'm sure, but it's a very different design, not just a more relaxed attitude to assignment. Regadrds,
-- Rowan Collins [IMSoP]

Marc Bennewitz

10 years ago
On 05/24/2016 11:57 AM, Rowan Collins wrote:
> On 24/05/2016 06:45, Jesse Schalken wrote: >> I'm curious, what is it about $this that makes it special in the first >> place? Can't it be a normal local variable that happens to already be >> assigned at the start of a method? > > There are a few things that take advantage of its specialness, e.g. > > - binding a closure to an object changes the meaning of $this in a way > very different from assigning it into scope with "use($this)" > - a method declared static can detect and throw errors on anything > referencing $this > - when calling parent::foo() from an instance method, the value of > $this needs to be set appropriately on the new method; being able to > reassign $this could lead to some odd behaviour there > > Python's approach is certainly valid, and leads to some different > useful properties, I'm sure, but it's a very different design, not > just a more relaxed attitude to assignment.
As of $this is a very special variable where only the engine is (or should) be allowed to change. I would like to ask you if it wouldn't be better to NOT define $this as a special variable including a lot of code to make sure this variable doesn't get re-assigned but instead define this as a keyword like self where the syntax makes sure it can't be re-assigned and it's less special and simpler to learn for beginners. I know it would be a huge BC break but for me it sounds more "right" and could also be introduced in parallel to $this for a long long time but without a lot of overplayed code for $this. Thanks, Marc

Rowan Collins

10 years ago
On 24/05/2016 20:21, Marc Bennewitz wrote:
> As of $this is a very special variable where only the engine is (or > should) be allowed to change. > I would like to ask you if it wouldn't be better to NOT define $this > as a special variable > including a lot of code to make sure this variable doesn't get > re-assigned > but instead define this as a keyword like self where the syntax makes > sure it can't be re-assigned > and it's less special and simpler to learn for beginners.
It's an interesting concept, but most of the time $this *does* behave like a variable - it's not just a way of accessing scope like "self". You can write "foo($this)", "$bar = $this", even "echo $this" (if __toString is defined). So any syntax that made it look unlike a variable would have the opposite learning problem - how come I can use it like a variable, but it looks like something else? There's also rather a shortage of syntax that doesn't already mean something... Regards,
-- Rowan Collins [IMSoP]

Dmitry Stogov

10 years ago
changing "$this" into "this" is not an option. This would break 90% of PHP code :) ________________________________________ From: Marc Bennewitz <dev@mabe.berlin> Sent: Tuesday, May 24, 2016 10:21:02 PM To: internals@lists.php.net Subject: Re: [PHP-DEV] [RFC] Fix inconsistent behavior of $this variable On 05/24/2016 11:57 AM, Rowan Collins wrote:
> On 24/05/2016 06:45, Jesse Schalken wrote: >> I'm curious, what is it about $this that makes it special in the first >> place? Can't it be a normal local variable that happens to already be >> assigned at the start of a method? > > There are a few things that take advantage of its specialness, e.g. > > - binding a closure to an object changes the meaning of $this in a way > very different from assigning it into scope with "use($this)" > - a method declared static can detect and throw errors on anything > referencing $this > - when calling parent::foo() from an instance method, the value of > $this needs to be set appropriately on the new method; being able to > reassign $this could lead to some odd behaviour there > > Python's approach is certainly valid, and leads to some different > useful properties, I'm sure, but it's a very different design, not > just a more relaxed attitude to assignment.
As of $this is a very special variable where only the engine is (or should) be allowed to change. I would like to ask you if it wouldn't be better to NOT define $this as a special variable including a lot of code to make sure this variable doesn't get re-assigned but instead define this as a keyword like self where the syntax makes sure it can't be re-assigned and it's less special and simpler to learn for beginners. I know it would be a huge BC break but for me it sounds more "right" and could also be introduced in parallel to $this for a long long time but without a lot of overplayed code for $this. Thanks, Marc
> > Regadrds,
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php

Stas Malyshev

10 years ago
Hi!
> Please review the RFC. > > It proposes to fix all known inconsistencies related to handling of special $this variable. > > https://wiki.php.net/rfc/this_var
What is the reason behind all these changes? Does it serve some bigger purpose? I'm not sure I currently see a reason to go to all these lengths. Sure, you can re-assign $this and make things weird. But I don't see why it's important to prevent it. It seems to add a lot of code, including checks in various places that would slow down things (and since these checks need to be done in each and every place we deal with local variables, it is also a very brittle design - each time we change or add anything there we'd need to remember forever to include special case for "this"). Also notes: 1. How static __call is a thing? That looks like something that makes no sense at all. 2. Why get_defined_vars() shouldn't show $this?
-- Stas Malyshev smalyshev@gmail.com

Dmitry Stogov

10 years ago
On 05/24/2016 09:54 AM, Stanislav Malyshev wrote:
> Hi! > >> Please review the RFC. >> >> It proposes to fix all known inconsistencies related to handling of special $this variable. >> >> https://wiki.php.net/rfc/this_var > What is the reason behind all these changes? Does it serve some bigger > purpose?
I started from attempt to eliminate second internal way to access $this variable. This disclosed all these inconsistencies.
> I'm not sure I currently see a reason to go to all these > lengths. Sure, you can re-assign $this and make things weird. But I > don't see why it's important to prevent it.
Keeping inconsistent behavior isn't good as well.
> It seems to add a lot of > code, including checks in various places that would slow down things > (and since these checks need to be done in each and every place we deal > with local variables, it is also a very brittle design - each time we > change or add anything there we'd need to remember forever to include > special case for "this").
Actually, $this may be assigned to local variable in run-time only in 3 places: through $$, extract() and parse_str()/1. If we remove this checks, we go back to 7.0 behavior - we create a local variable $this, that has nothing in common with real internal $this stored in EX(This).
> > Also notes: > 1. How static __call is a thing? That looks like something that makes no > sense at all.
The same for me. I got to know about static __call() and its special behavior from test suite. :) See tests/classes/__call_007.phpt
> 2. Why get_defined_vars() shouldn't show $this? >
In most cases it doesn't show $this in 7.0. Thanks. Dmitry.

Stas Malyshev

10 years ago
Hi!
> Keeping inconsistent behavior isn't good as well.
It's not good, but it's not also very bad. Nobody really does that, so whatever happens in these cases is mostly irrelevant. Did you test performance impact of those changes?
> Actually, $this may be assigned to local variable in run-time only in 3 > places: through $$, extract() and parse_str()/1.
For now, maybe. But every time we do something with local symbol table, we'd have to do special case for this. E.g., throretically, what if we wanted to add function to Closure that allows to access to captured scope - we'd need to special-case $this there. Etc...
> If we remove this checks, we go back to 7.0 behavior - we create a local > variable $this, that has nothing in common with real internal $this > stored in EX(This).
That's not good, but maybe we could make them agree in some way?
> In most cases it doesn't show $this in 7.0.
Right. But you're changing 7.0 behavior anyway?
-- Stas Malyshev smalyshev@gmail.com

Dmitry Stogov

10 years ago
On 05/24/2016 11:04 AM, Stanislav Malyshev wrote:
> Hi! > >> Keeping inconsistent behavior isn't good as well. > It's not good, but it's not also very bad. Nobody really does that, so > whatever happens in these cases is mostly irrelevant.
For me it's easier to check and fix all inconsistencies at once. I may set an additional voting question about performing these run-time checks and throwing corresponding exception...
> > Did you test performance impact of those changes?
Of course. It's invisible on real-life apps even in terms of instruction retired.
> >> Actually, $this may be assigned to local variable in run-time only in 3 >> places: through $$, extract() and parse_str()/1. > For now, maybe. But every time we do something with local symbol table, > we'd have to do special case for this. E.g., throretically, what if we > wanted to add function to Closure that allows to access to captured > scope - we'd need to special-case $this there. Etc...
We shouldn't access local variables in irregular way. This irregularity makes extract() and parse_str() to be special and they require special handling. See Nikita's RFC https://wiki.php.net/rfc/forbid_dynamic_scope_introspection
> >> If we remove this checks, we go back to 7.0 behavior - we create a local >> variable $this, that has nothing in common with real internal $this >> stored in EX(This). > That's not good, but maybe we could make them agree in some way?
What do you mean? Change the real $this to something else in the middle of the method???
> >> In most cases it doesn't show $this in 7.0. > Right. But you're changing 7.0 behavior anyway? >
Right. And I don't see reason to show $this in get_defined_vars(), because it's special, and not really a local variable. Thanks. Dmitry,

Fleshgrinder

10 years ago
On 5/23/2016 10:24 PM, Dmitry Stogov wrote:
> https://wiki.php.net/rfc/this_var >
Hi Dmitry, could you extend the RFC with an additional section that mentions to update corresponding manual pages, e.g.: https://secure.php.net/language.variables.basics There is a regular expression on that page that looks like the following and is often referred to by people explaining variable names in PHP: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* I would propose to update this to the following more complete PCRE: /^\$?(?!this)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/D @nikic this is also important for your RFC regarding empty variable names because the PCRE would need to be updated once more too: /^\$?(?!this)[a-zA-Z_\x7f-\xff]?[a-zA-Z0-9_\x7f-\xff]*$/D Of course the sentence preceding the regular expression would also require an update. There might be more pages that I am not aware of but we could ask someone from the documentation team to help us here. The above one is definitely the most important one and it should imho be included in the RFC.
-- Richard "Fleshgrinder" Fussenegger

Dmitry Stogov

10 years ago
Hi Richard, $this is still confirm to variable syntax. It's just a special variable. I think, we should keep lexical rules unchanged. Thanks. Dmitry. ________________________________________ From: Fleshgrinder <php@fleshgrinder.com> Sent: Tuesday, May 31, 2016 7:19:57 PM To: Dmitry Stogov; internals; Nikita Popov Subject: Re: [PHP-DEV] [RFC] Fix inconsistent behavior of $this variable On 5/23/2016 10:24 PM, Dmitry Stogov wrote:
> https://wiki.php.net/rfc/this_var >
Hi Dmitry, could you extend the RFC with an additional section that mentions to update corresponding manual pages, e.g.: https://secure.php.net/language.variables.basics There is a regular expression on that page that looks like the following and is often referred to by people explaining variable names in PHP: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* I would propose to update this to the following more complete PCRE: /^\$?(?!this)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/D @nikic this is also important for your RFC regarding empty variable names because the PCRE would need to be updated once more too: /^\$?(?!this)[a-zA-Z_\x7f-\xff]?[a-zA-Z0-9_\x7f-\xff]*$/D Of course the sentence preceding the regular expression would also require an update. There might be more pages that I am not aware of but we could ask someone from the documentation team to help us here. The above one is definitely the most important one and it should imho be included in the RFC.
-- Richard "Fleshgrinder" Fussenegger

Fleshgrinder

10 years ago
On 5/31/2016 6:39 PM, Dmitry Stogov wrote:
> Hi Richard, > > $this is still confirm to variable syntax. It's just a special variable. > I think, we should keep lexical rules unchanged. >
The page is about user assignable variable names. If I understand it correct we cannot to the following anymore in userland: $this = 'my value'; Hence `$this` is correct to lexical rules but not in the context of variables that I can use to assign something too. Hence the change of the manual page. I did not say anything about lexical changes. Note well that the above is already not possible in many situations: php -r '$this = "my value";' Fatal error: Cannot re-assign $this in Command line code on line 1 TL;DR $this does conform to syntax but not to basic PHP userland rules for variable naming (what the manual page is about).
-- Richard "Fleshgrinder" Fussenegger

Christoph Becker

10 years ago
On 31.05.2016 at 18:55, Fleshgrinder wrote:
> On 5/31/2016 6:39 PM, Dmitry Stogov wrote: >> >> $this is still confirm to variable syntax. It's just a special variable. >> I think, we should keep lexical rules unchanged. > > TL;DR $this does conform to syntax but not to basic PHP userland rules > for variable naming (what the manual page is about).
I agree with Dmitry here. While the page is about variables, the paragraph is about variable names, and it is already noted there that: | $this is a special variable that can't be assigned In other sections of the manual, $this is described as `pseudo-variable`. However, it is still a variable, even though it can't be assigned to – I think of it as read-only (final) variable. Hence, it shouldn't be excluded from the valid variable names.
-- Christoph M. Becker