2010-08-14 137 views
3

我有一個父對象,我在我的應用程序中用於一般CRUD - 它具有基本保存&檢索方法,因此我無需將它們重新包括在我的所有對象中。我的大部分子對象都擴展了這個基礎對象。這工作得很好,但我發現檢索序列化的子對象有問題。我在創建子實例的父對象中使用「檢索」方法,然後從反序列化子的屬性中填充自身 - 這意味着可以「自我解序列化」對象。PHP在父項中訪問子項的私有屬性

唯一的問題是 - 如果子對象具有受保護屬性或私有屬性,則父對象無法讀取它,因此它在檢索過程中不會被拾取。

所以我正在尋找更好的方法來「自我反序列化」或一種方法來允許父對象「看到」受保護的屬性 - 但只有在檢索過程中。代碼

例子:

BaseObject { 

protected $someparentProperty; 

public function retrieve() { 

    $serialized = file_get_contents(SOME_FILENAME); 
    $temp = unserialize($serialized); 
    foreach($temp as $propertyName => $propertyValue) { 
    $this->$propertyName = $propertyValue; 
    }  

} 

public function save() { 

    file_put_contents(SOME_FILENAME, serialize($this)); 
} 
} 

class ChildObject extends BaseObject { 

private $unretrievableProperty; 

public setProp($val) { 
    $this->unretrivableProperty = $val; 
} 
} 

$tester = new ChildObject(); 
$tester->setProp("test"); 
$tester->save(); 

$cleanTester = new ChildObject(); 
$cleanTester->retrieve(); 
// $cleanTester->unretrievableProperty will not be set 

編輯:應該說 「私人」 不受保護子屬性。

回答

0

它似乎並不認爲同一類的可見性政策適用於iherited /父類。 php文檔沒有解決這個問題。

我建議你聲明檢索方法是靜態的,並通過靜態調用獲取$ cleanTester,而不是當前的「自我反序列化」方法。

static function retrieve() { 
    $serialized = file_get_contents(SOME_FILENAME); 
    return unserialize($serialized); 
} 

[...] 

$cleanTester = BaseObject::retrieve(); 

或者你也可以利用__get()方法來訪問不可訪問的屬性......我相信這可以被添加到BaseObject類,並獲取從子類的保護性能。由於同一班級的可見性政策應適用於BaseObject,因此您可以將__get()方法定義爲「私人」或「受保護」。

BaseObject { 
    private function __get($propertyName) { 
    if(property_exists($this,$propertyName)) 
     return $this->{$propertyName}; 

    return null; 
    } 
+0

感謝。靜態方法看起來是可行的 - 但事實上,一些子對象需要安裝,並且在可以計算出應該從中檢索的文件名之前進行一些處理。 __get已經用於這個目的 - 但是當我遍歷對象的屬性時,父類也不知道需要什麼屬性。我想我需要看看迭代方法 - 感謝指針。 – Hippyjim 2010-08-14 17:07:41

0

怎麼樣在子對象的getProperty()函數,返回$這個 - > unretrievableProperty

+0

謝謝 - 不錯的想法,但作爲baseobject不知道孩子的特性,也不會知道要問什麼 – Hippyjim 2010-08-14 17:05:54

2

嘗試這樣的:

abstract class ParentClass 
{ 
    protected abstract function GetChildProperty(); 

    public function main() 
    { 
    $value = $this->GetChildProperty(); 
    } 
} 

class ChildClass extends ParentClass 
{ 
    private $priv_prop = "somevalue"; 

    protected function GetChildProperty() 
    { 
    return $this->priv_prop; 
    } 
} 
0

的最可能的回答解決這個問題是使用反射

例子:

$_SESSION[''] = ''; // init 

class Base { 
    public function set_proxy(){ 
     $reflectionClass = new ReflectionClass($this); 
     $ar = $reflectionClass->getDefaultProperties(); 

     !isset($ar['host']) or $_SESSION['host'] = $ar['host']; 
    } 
} 

class Son1 extends Base { 
    private $host = '2.2.2.2'; 
} 

class Son2 extends Son1 { 

} 


$son1 = new Son1(); 
$son1->set_proxy(); 
var_dump($_SESSION); // array(2) { [""]=> string(0) "" ["host"]=> string(7) "2.2.2.2" } 

unset($_SESSION); 
$_SESSION[''] = ''; // init 

$son2 = new Son2(); 
$son2->set_proxy(); 
var_dump($_SESSION); // array(1) { [""]=> string(0) "" }