Reputation: 1878
here is what my code looks like
i have two forms:
class Form_1 extends Form_Abstract {
public $iId = 1;
}
class Form_2 extends Form_1 {
public $iId = 2;
}
i expect the code behave like this:
$oForm = new Form_2;
echo $oForm->getId(); // it returns '2'
echo $oForm->getParentId(); // i expect it returns '1'
here is my Form_Abstract class:
class Form_Abstract {
public $iId = 0;
public function getId() {
return $this->iId;
}
/**
this method will be called from a child instance
*/
public function getParentId() {
return parent::$iId;
}
}
but it throws a Fatal Error:
Fatal error: Cannot access parent:: when current class scope has no parent
please help me with the method getParentId()
PS: i know the reason of what happens, i am seeking for the solution.
Upvotes: 2
Views: 9965
Reputation: 5220
You have to use Reflection Api to access the parent class' property default value. Substitute getParentId, in Form_Abstract
, with this, and all works fine:
public function getParentId() {
$refclass = new ReflectionClass($this);
$refparent = $refclass->getParentClass();
$def_props = $refparent->getDefaultProperties();
return $def_props['iId'];
}
Clearly you cannot call getParentId() in the root class, so it's better to check if a parent class exists.
UDATE:
You can do the same with classes/objects functions:
public function getParentId() {
$def_values = get_class_vars(get_parent_class($this));
return $def_values['iId'];
}
Upvotes: 5
Reputation: 1878
i made it work by this:
public function getParentId() {
$sClass = get_parent_class($this);
$tmp = new $sClass;
return $tmp->iId;
}
BUT is it a standard solution, does it have any performance issue?
Upvotes: 0
Reputation: 401012
I don't think it is even possible to access the "parent"'s version of $iId
: you don't actually re-define it in the child class : you only chance the value that was defined in the parent's class.
To makes things very simple : when you declare the Form_2
class that extends Form_1
, it takes all the properties and methods of Form_2
, and put them in Form_1
, overriding what was already existing there.
There is no longer "two distinct classes" : there is only one resulting object, that's both Form_1
and Form_2
at the same time.
And here's an example that kind of -- I hope -- will help understand what I mean :
class Form_Abstract {}
class Form_1 extends Form_Abstract {
public $iId = 1;
public function methodInParent() {
var_dump($this);
}
}
class Form_2 extends Form_1 {
public $iId = 2;
public function tryingToGetParentProperty() {
var_dump(parent::$iId);
}
}
$form2 = new Form_2();
$form2->methodInParent();
$form2->tryingToGetParentProperty();
Using this portion of code, the call to $form2->methodInParent()
will get you :
object(Form_2)#1 (1) {
["iId"]=>
int(2)
}
i.e. even if calling/executing a method that's defined in the parent's class, the $iId
property is still the value defined in the child class : there is one, and only one, version of that property !
And the call to $form2->tryingToGetParentProperty()
will get you :
Fatal error: Access to undeclared static property: Form_1::$iId
As there is no static
property called $iId
in Form_1
.
I suppose a solution to avoid that situation would be to declare $iId
as static
-- but note that it would change the meaning of your code, and the way it behaves !
i.e. the static
variable will be shared accross all instances of the class -- which is probably not what you want ^^
Upvotes: 1
Reputation: 53960
The error is because you are calling the parent of a class that does not have a parent (it does not extend an existing class).
Upvotes: 3