2011-03-24 117 views
4
<?php 

abstract class AbstractClass 
{ 
    public function __get($theName) 
    { 
     return (isset($this->$theName)) ? $this->$theName : NULL; 
    } 

    public function __set($theName, $theValue) 
    { 
     if (false === property_exists(get_class(), $theName)) { 
      throw new Exception(get_class()." does not have '".$theName."' property."); 
     } else { 
      $this->$theName = $theValue; 
     } 
    } 
} 

class ConcreteClass extends AbstractClass 
{ 
     private $x; 
     private $y; 

     public function __construct($theX, $theY) 
     { 
      $this->x = $theX; 
      $this->y = $theY; 
     } 
} 

$concreteClass = new ConcreteClass(10, 20); 

var_dump($concreteClass->x); 

是否有某種方法來完成這項工作,或者我將不得不將這些魔術方法添加到擴展類中?魔法方法(__get,__set)無法在擴展類中使用?

+0

究竟出了什麼問題?是空的?你可能需要在基類中設置$ x和$ y才能工作。 – dqhendricks 2011-03-24 15:16:30

回答

7

這會工作:

public function __get($theName) 
{ 
    if(property_exists($this, $theName)) { 
     $reflection = new ReflectionProperty($this, $theName); 
     $reflection->setAccessible($theName); 
     return $reflection->getValue($this); 
    } 
} 

IMO,你不應該使用__get__set作爲getter和setter的替代品。由於它們在嘗試訪問不可訪問的屬性時被觸發,因此它們與錯誤處理關聯更多。而且它們也比常規的getter或setter慢得多。

+0

謝謝。我想讓自己的生活變得更輕鬆,只有一個具有定義的getter和setters的類的抽象類。我已經有太多的get和set方法了。 – 2011-03-24 15:35:53

5

您的問題是在ConcreteClass中設置的$ x和$ y成員是私有的。由於__get()方法是在父類中定義的,因此它不具有對子類的私有成員的訪問權限(因爲私有成員只能由類本身訪問,而不能由任何子類或父類訪問)。爲了讓他們對父類可見,他們必須是protectedpublic。對於你的情況,你必須使用保護來保持課堂以外的神奇功能。

然而,這是一個非常奇怪的做法充其量。如果可以通過魔術方法訪問這些變量,首先將它們設置爲私有是沒有多大意義的。

+0

這是我的問題。使很多意義設置受到保護。然而,這不是一個奇怪的做法......如果你正確地編寫了你的​​魔術函數,那麼它或者作爲一個簡單的訪問函數(獲取/設置值)......但它首先檢查其他的「get_PROPERTY」或「set_PROPERTY」功能已被指定。如果他們有,那些被返回。我發現這很有用,因爲我的大部分屬性可以正常獲取/設置,但有些應用了操作(即trim()或其他)或驗證邏輯。 – MikeMurko 2011-05-11 22:43:06

1

這是因爲您的xy屬於ConcreteClass,而父母s functions only work for parent的屬性。例如,如果你有:

abstract class AbstractClass 
{ 
    private $x; 
//... 
} 
class ConcreteClass extends AbstractClass 
{ 
     private $y; 

     public function __construct($theX, $theY) 
    //... 

那麼它會工作。父母不能訪問孩子的私人財產,如果碰到這個,你必須重新考慮你的對象結構。

更新

正如Rinuwise說,你可以讓xy可見通過聲明它們的保護或公開,但它仍然是錯誤的邏輯。

另外,作爲一種替代方案,您可以將AbstractClass中的__get方法複製粘貼到ConcreteClass中,從而以父方式訪問私有屬性的父類;但再次「你可以做到這一點」並不意味着「你必須做到這一點」:)。