no PHP error thrown when private property accessed or modified by subclass
This is another ‘Gotcha’ moment that i want to share with you.
I don’t often declare a PHP class property as ‘private’. But, recently, I was copying some PHP code from out of a book. The code had a parent abstract class which had some private properties.
i.e
...abstract class ParentAbstract {
private $property ='init';
...
I modified it to suit my needs and extended it by writing a child class.
When testing it, I noticed some really strange behaviour. A method within my subclass was modifying a property. But, later in the code, a getter method in the parent class was returning a value that implied that the property was not getting modified.
I noticed that the property had been declared ‘private’ in the parent class and suspected that this was causing the problem.
I understand that a subclass cannot modify a private property of a parent class. But…
I was surprised to discover that when a subclass attempts to modify its parent’s private properties - there are no errors or warnings thrown.
The property of the subclass and the property of the parent class appear to be treated as two seperate properties. Each has the same name and each with a different scope.
Luckily I had no need to make my property ‘private’ (The only reason it was private in the first place was cos I was just doing some mindless copying of code). So, for me, the easy solution was to simply change its access type declaration to be ‘protected’.
If it was essential for the property to have been declared as ‘private’ - i guess i could have made sure that subclasses always used setter and getter methods (that are declared within the parent class) to modify the property.
Here is some example code to explain my experience:
<?php
/**
*@desc just some test classes to work out some weirdness that is occuring when trying to modify a private property from a subclass
*/
abstract class ParentAbstract
{
private $property ='init';
public function modify_property_within_parent()
{
$this->property = 'modifiedinparent';
}
public function PARENT_get_property()
{
return $this->property;
}
}
class Child extends ParentAbstract
{
public function set_property($value)
{
$this->property = $value;
}
public function get_property()
{
return $this->property;
}
public function append_property($str)
{
$this->property .= $str;
}
public function echo_property()
{
echo $this->property;
}
}
//client code
$str .= 'PHP version:'. phpversion();
$obj = new Child();
$str .= 'initialized property from perspective of child:'.$obj->get_property();
$obj->modify_property_within_parent();
$str .= 'modified property from perspective of child:'.$obj->get_property();
$str .= 'modified property from perspective of parent:'.$obj->PARENT_get_property();
$obj->append_property('Extra');
$str .= 'after appended to property from perspective of child:'.$obj->get_property();
$obj->set_property('hello');
$str .= 'after set in child from perspective of child:' . $obj->get_property();
$obj->append_property('Extra2');
$str .= 'after appended to property2 from perspective of child:'.$obj->get_property();
echo($str);
prints
——–
PHP version:5.2.8
initialized property from perspective of child:
modified property from perspective of child:
modified property from perspective of parent:modifiedinparent
after appended to property from perspective of child:Extra
after set in child from perspective of child:hello
after appended to property2 from perspective of child:helloExtra2
——–
Just for the record
This is a summary of internet searches I did when trying to work out what was going on:
- php bug 5.2 private properties
- php bug private proiperty accessed by subclass no error
- php bug private property accessed by subclass no error
- php no error thrown when private property accessed by subclass