2010-08-14 4 views
3

J'ai un objet parent que j'utilise pour le CRUD général dans mes applications - il a des méthodes de récupération de base & pour ne pas avoir à les réintroduire dans tous mes objets. La plupart de mes objets enfants étendent cet objet de base. Cela a fonctionné correctement, mais je trouve un problème avec la récupération d'un objet enfant sérialisé. J'utilise une méthode "retrieve" dans l'objet parent qui crée une instance de l'enfant, puis se remplit à partir des propriétés de l'enfant non sérialisé - ce qui signifie qu'il peut "se désérialiser" l'objet. Seul le problème est le suivant: si l'objet enfant a une propriété protégée ou privée, l'objet parent ne peut pas le lire, il n'est donc pas détecté pendant la récupération. Je cherche donc une meilleure façon de "se désintégrer soi-même" ou un moyen de permettre à un objet parent de "voir" les propriétés protégées - mais seulement pendant le processus de récupération.PHP Accès aux propriétés privées d'un enfant dans le parent

Exemple de code:

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 

ÉDITÉ: aurait dû dire propriétés enfant "privées" non protégés.

Répondre

0

Il ne semble pas que la politique même de la visibilité de la classe applique aux classes iherited/parents. La documentation PHP ne traite pas cela.

Je suggérerais que vous avez déclaré la méthode de récupération statique et ai récupéré le $ cleanTester via un appel statique plutôt que votre approche "self unserialize" actuelle.

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

[...] 

$cleanTester = BaseObject::retrieve(); 

Ou vous pouvez utiliser la méthode __get() pour accéder aux propriétés inaccessibles ... Je pense que cela pourrait être ajouté à la classe BaseObject quérir propriétés protégées de la classe des enfants. Étant donné que la même stratégie de visibilité de classe doit s'appliquer à BaseObject, vous pouvez définir la méthode __get() privée ou protégée.

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

    return null; 
    } 
+0

Merci. La méthode statique semble viable, mais pour le fait que certains des objets enfants doivent être instanciés, et pour effectuer un traitement avant de pouvoir trouver le nom de fichier, ils doivent être récupérés. Le __get est déjà utilisé, à peu près dans ce but - mais comme je parcours les propriétés de l'objet, le parent ne saura pas quelles propriétés demander. Je suppose que je dois regarder la méthode d'itération - merci pour le pointeur. – Hippyjim

0

que diriez-vous d'une fonction getProperty() dans l'objet enfant qui retourne $ this-> unretrievableProperty

+0

Merci - bonne idée, mais comme BaseObject ne saura pas les propriétés de l'enfant, il ne saura pas quoi demander – Hippyjim

2

essayer comme ceci:

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

La meilleure réponse possible de résoudre ce problème est d'utiliser des réflexions .

Exemple:

$_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) "" } 
Questions connexes