2010-08-14 95 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) "" }