According to official documentation :
Nesting an anonymous class inside another class does not give access to any private or protected method, or properties of the outer class. To use the protected methods and properties of the outer class, the anonymous class can extend the outer class. To use the private properties of the outer class in the anonymous class, they must be passed through the constructor.
That is, the constructor of the anonymous class must be defined by passing the private values to be used. For example:
<?php
class MyClass
{
private $prop = "teste";
public function test()
{
$class = new class($this->prop) {
public function __construct($prop)
{
$this->prop = $prop;
}
public function run()
{
echo $this->prop, PHP_EOL;
}
};
$class->run();
}
}
$obj = new MyClass();
$obj->test();
See working at Ideone
Notice that it is the desired value that must be passed through the constructor. Passing the $this
object as a parameter and attempting to access the private attribute of it within the anonymous class results in a fatal error. See below:
<?php
class MyClass
{
private $prop = "teste";
public function test()
{
$class = new class($this) {
public function __construct($obj)
{
$this->obj = $obj;
}
public function run()
{
echo $this->obj->prop, PHP_EOL;
}
};
$class->run();
}
}
$obj = new MyClass();
$obj->test();
See working at Ideone .
That is, even passing the object itself and using it to access the private attribute within the class itself results in an error. This is because PHP interprets the context of the anonymous class as something isolated from the parent class, not assigning the access permissions to the object's private attributes and methods.
Changeable or unchanging attribute
If the attribute passed to the anonymous class is immutable, it can not change the original value of the attribute in the parent class except when the value is passed by reference. By default, immutable attributes are passed by value in PHP. To verify, simply try to change the value of $prop
within the anonymous class and then check the value of this attribute in the parent class:
<?php
class MyClass
{
public $prop = "teste";
public function test()
{
$class = new class($this->prop) {
public function __construct($prop)
{
$this->prop = $prop;
}
public function run()
{
$this->prop = "teste na classe anônima";
echo $this->prop, PHP_EOL;
}
};
$class->run();
}
}
$obj = new MyClass();
$obj->test();
echo $obj->prop, PHP_EOL;
See working at Ideone .
Output output is:
teste na classe anônima
teste
That is, because the attribute is a string and is an immutable type, the value was passed to the anonymous class as value and was not changed in the parent class. Basically the object was copied when passed to the anonymous class and it does not have the reference to the original object.
Now, if the value is of a changeable type, an object of class Foo, for example, the behavior is different:
<?php
class Foo {
public function __construct($prop) {
$this->prop = $prop;
}
public function __toString() {
return $this->prop;
}
}
class MyClass
{
public function __construct()
{
$this->prop = new Foo("test");
}
public function test()
{
$class = new class($this->prop) {
public function __construct($prop)
{
$this->prop = $prop;
}
public function run()
{
$this->prop->prop = "Teste na classe anônima";
echo $this->prop, PHP_EOL;
}
};
$class->run();
}
}
$obj = new MyClass();
$obj->test();
echo $obj->prop, PHP_EOL;
See working at Ideone .
The result is:
Teste na classe anônima
Teste na classe anônima
That is, the original value of the attribute in the parent class has also changed. Since the object passed to the anonymous class is changeable, the object is passed by reference , so any changes made within the anonymous class will also affect the object in the parent class because they are the same object.