rfc:this_var

This is an old revision of the document!


PHP RFC: Fix inconsistent behavior of $this variable

Introduction

Historically PHP implementation accessed special $this variable using two different methods. In some cases this might lead to significant inconsistency, when $this accessed through different methods might have different values.

class C {
  function foo() {
    var_dump($this);
  }
  function bar() {
    $a="this";
    $$a=42;
    var_dump($this); // prints int(42)
    $this->foo();    // prints object(C)#1 (0) {}
  }
}
$x = new C;
$x->bar();

This RFC proposes disabling modification of $this variable using “magic code” and make $this always behave in the same way.

Proposal

Disable using $this as parameter

The following code worked in PHP 7, but will emit compilation error in PHP 7.1

function foo($this) { // Fatal error: Cannot use $this as parameter
}

Disable using $this as static variable

The following code worked in PHP 7, but will emit compilation error in PHP 7.1

static $this; // Fatal error: Cannot use $this as static variable

Disable using $this as global variable

The following code worked in PHP 7, but will emit compilation error in PHP 7.1

global $this; // Fatal error: Cannot use $this as global variable

Disable using $this as catch variable

The following code worked in PHP 7, but will emit compilation error in PHP 7.1

try {
  ...
} catch (Exception $this) { // Fatal error: Cannot re-assign $this
}

Disable using $this as foreach value variable

The following code worked in PHP 7, but will emit compilation error in PHP 7.1

foreach ($a as $this) { // Fatal error: Cannot re-assign $this
}

Disable ability to unset() $this

It's not allowed to re-assign $this, so why it should be allowed to unset() it. The following code worked in PHP 7, but will emit compilation error in PHP 7.1

unset($this); // Fatal error: Cannot unset $this

Disable ability to re-assign $this indirectly through $$

An attempt to re-assign $this through $$ assignment will lead to throwing of Error exception.

$a = "this";
$$a = 42; // throw new Error("Cannot re-assign $this")

It's still possible to read $this value through $$.

Disable ability to re-assign $this indirectly through reference

Indirect re-assign $this through reference won't make effect in PHP 7.1

class C {
  function foo(){
    $a =& $this;
    $a = 42;
    var_dump($this); // prints object(C)#1 (0) {}, php-7.0 printed int(42)
  }
}
$x = new C;
$x->foo();

Always show true $this value in magic method __call()

In PHP 7.0 and below $this in static magic method __call() had value NULL. However it was possible to access properties and call object methods.

class C {
  static function __call($name, $args) {
    var_dump($this); // prints object(C)#1 (0) {}, php-7.0 printed NULL
    $this->test();   // prints "ops"
  }
  funcriont test() {
    echo "ops\n"; 
  }
}
$x = new C;
$x->foo();

Backward Incompatible Changes

All the BC breaks are intentional and they are described in the proposal section.

Proposed PHP Version(s)

PHP 7.1

RFC Impact

To SAPIs

none

To Existing Extensions

none

To Opcache

The proposed implementation is compatible with opcache

Open Issues

none

Proposed Voting Choices

The vote is a straight Yes/No vote, that requires a 2/3 majority. The voting will begin on Jun 6 and will close on Jun 16.

Patches and Tests

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

Rejected Features

Keep this updated with features that were discussed on the mail lists.

rfc/this_var.1464043781.txt.gz · Last modified: 2017/09/22 13:28 (external edit)