我是PHP的OOP新手。我有以下问题: 我有一个名为'User'的父类和2个子类'Business'和'Standaard'。
我的父类看起来像这样:
class User {
protected $m_iId;
protected $m_iFoto;
protected $m_sEmail;
/*Constructor*/
public function __construct(){
$this->Id = -1;
$this->Foto = "";
$this->Email = "";
}
/*Setter*/
public function __set($p_sProperty, $p_sValue){
switch($p_sProperty){
case "Id":
if(is_numeric($p_sValue) && $p_sValue !== -1){
$iNumber = intVal($p_sValue);
if($iNumber >= -1){
$this->m_iId = $p_sValue;
}
else{
echo("Not a valid id: ".$p_sValue);
}
}
break;
case "Foto":
if(is_numeric($p_sValue) && $p_sValue !== -1){
$iNumber = intVal($p_sValue);
if($iNumber >= -1){
$this->m_iFoto = $p_sValue;
}
else{
echo("Not a valid Foto_id: ".$p_sValue);
}
}
break;
case "Email":
$this->m_sEmail = $p_sValue;
break;
default: echo("Unknown property: ".$p_sProperty);
}
}
/*Getter*/
public function __get($p_sProperty){
$vResult = null;
switch($p_sProperty){
case "Id";
$vResult = $this->m_iId;
break;
case "Foto";
$vResult = $this->m_iFoto;
break;
case "Email";
$vResult = $this->m_sEmail;
break;
default: echo("Unknown property: ".$p_sProperty);
}
return $vResult;
}
}
小孩看起来像这样:
class UserStandaard extends User {
//velden die bereikbaar zijn
protected $m_sName;
/*Constructor*/
public function __construct(){
parent::__construct();
$this->Name = "";
}
/*Setter*/
public function __set($p_sProperty, $p_sValue){
switch($p_sProperty){
case "Name":
$this->m_sName = $p_sValue;
break;
default: echo("Unknown property: ".$p_sProperty);
}
}
/*Getter*/
public function __get($p_sProperty){
$vResult = null;
switch($p_sProperty){
case "Name";
$vResult = $this->m_sName;
break;
default: echo("Unknown property: ".$p_sProperty);
}
return $vResult;
}
}
我的问题如下: 我如何申请ID? 我想做点什么:
$oUser = new UserStandaard();
echo $oUser->Id;
但这不起作用......它不断回响
Unknown property: Id
谢谢!
答案 0 :(得分:2)
问题是__get
和__set
的派生类实现不会调用基类实现。这不会自动发生,您需要明确地执行此操作:
class UserStandaard extends User {
/*Setter*/
public function __set($p_sProperty, $p_sValue){
parent::__set($p_sProperty, $p_sValue);
// your current code follows
}
}
但是,这仍然无效,因为现在您的父实现只会识别它知道的三个属性。似乎没有直接的方法来处理这个问题,这意味着您的设计存在问题,需要进行修改。
结构__get
和__set
更具可插性(示例待处理)。我的意思是他们认识到的属性集不应该是硬编码的,因为这使得扩展它们非常困难。理想情况下,您需要为每个属性使用不同的getter和setter:
class User {
public function getName() { ... }
public function setName($name) { ... }
}
这样可以让代码保持良好,干净和分离。然后,您可以将__get
和__set
联系起来转发这些方法:
public function __get($name)
{
$getter = 'get'.ucfirst($name);
if (!method_exists($this, $getter)) {
die("This object does not have a $name property or a $getter method.");
}
return $this->$getter();
}
public function __set($name, $value)
{
$setter = 'set'.ucfirst($name);
if (!method_exists($this, $setter)) {
die("This object does not have a $name property or a $setter method.");
}
$this->$setter($value);
}
通过这种方式,您可以将每个属性分解为上面的getter和setter方法,并且绝对不需要在派生类中覆盖__get
和__set
。只需为您感兴趣的属性声明其他getter和setter,基类__get
/ __set
将正确转发到这些方法。
答案 1 :(得分:1)
这是因为您在UserStandaard类中的覆盖__get()
方法中没有Id。
/*Getter*/
public function __get($p_sProperty){
$vResult = null;
switch($p_sProperty){
case "Name";
$vResult = $this->m_sName;
break;
default: echo("Unknown property: ".$p_sProperty);
}
return $vResult;
}
但是你可能会认为这是在他的父母那里。
不,因为你已经覆盖了父方法。
您正在尝试使用__get和__set在User类中使用魔术方法重载属性,但是您在UserStandaaard类中覆盖这些函数。这两个函数只知道自己类中的属性,因为Userstandaard的__get方法不会调用它的父方法。但即使你这样做,也会失败,因为你使用switch-cases和不同的属性名称来实现你的魔术方法的方式。
因此,使用UserStandaard中的魔术方法只会知道1个属性,如果从User调用父方法,它只会知道父属性(如Jon所提到的)。
我会说改变你的设计,这是行不通的。
Jon有一个很好的例子说明它是如何运作的!
哦,对你说:Welkom bij stack-overflow! ;)