2017-07-05 4 views
-1

Après avoir lu this question Une idée pour mon problème était de mettre en œuvre la méthode dans les classes d'enfants comme:Comment parcourir les champs privés d'un enfant?

class Child { 
    private $childField = "Want to see"; 
    public $pubChildField = "Will see"; 

    public function method() 
    { 
     $assoc = []; // a associative array 
     foreach ($this as $field => $value) { 
      $assoc[$field] = doStuff($value); 
     } 
     return $assoc; 
    } 
} 
var_dump((new Child())->jsonSerialize()); 

Mais pour cela, je dois copycat le code dans chaque classe enfant. Pour faciliter la lecture, je veux factoriser en un (déjà existant) parentClass semblable à:

abstract class parentClass { 
    public function method() 
    { 
     $assoc = []; // a associative array 
     foreach ($this as $field => $value) { 
      $assoc[$field] = doStuff($value); 
     } 
     return $assoc; 
    } 
} 
class Child extends parentClass { 
    private $childField; 
    public $pubChildField; 
} 
var_dump((new Child())->jsonSerialize()); 

Les deux foreach ($this as $k=>$v) et get_object_vars() obtiendrez les champs publics de l'instance. J'ai besoin d'obtenir des champs privés pour la sérialisation.


Edit 1: Typo méthode abstraite - ce que je pensais

Edit 2: Clarifiée l'exemple

Edit 3: reformulé la question car il semblait être fausse idée

+4

'évidemment $ cela fait référence à la méthode abstraite' .... Non !!!! '$ this' fait référence à' l'instance'; '$ this' ne fait jamais référence à une classe –

+0

Pourquoi voulez-vous faire ça, Janseen? –

+0

Voici le manuel PHP avec les bases pour les objets et les classes en PHP: http://php.net/manual/fr/language.oop5.basic.php. Voici un peu plus sur Object Inheritance: http://php.net/manual/en/language.oop5.inheritance.php. Je pense que vous devriez regarder à travers eux. –

Répondre

1
  1. La classe abstraite traite des méthodes abstraites, non héritées. Je suppose que ces ne sont pas pertinents au problème (sinon, faites-en la valeur par défaut/classe de base).

  2. private limite la visibilité à la classe de béton - utiliser protected à la place.

Il me semble que vous avez seulement besoin de réutiliser le code. Vous pouvez rechercher des traits dans cette casse - les traits faisant partie d'une classe, et vous pouvez parcourir des domaines privés.

interface ArrayData { 
    public function toArray(): array; 
} 

trait ToArray { 
    public function toArray(): array { 
     $assoc = []; // a associative array 
     foreach ($this as $field => $value) { 
      $assoc[$field] = $value; 
     } 
     return $assoc; 
    } 
} 

class Foo implements ArrayData { 
    use ToArray; 

    private $childField = "Want to see"; 
    public $pubChildField = "Will see"; 
} 

$foo = new Foo(); 

var_dump($foo->toArray()); 
+0

hm ... en utilisant protégé semble être la solution la plus propre ... acceptant (même si elle ne résout pas la question formulée dans le titre) –

+0

@ S.Janssen Avec les traits, vous pouvez réutiliser le code et parcourir les champs privés. Peut-être que c'est ce que tu cherches. – shudder

0

La bonne solution est de déclarer la classe de base implements l'interface JsonSerializable et mettre en œuvre la méthode JsonSerializable::jsonSerialize() dans toutes les classes d'enfants. Vous pouvez le laisser non implémenté dans la classe de base pour forcer toutes les classes enfants à l'implémenter ou vous pouvez fournir une implémentation par défaut (return array();) dans la classe de base pour les classes enfants qui n'ont pas besoin d'être sérialisées.

L'implémentation dans chaque classe ne doit pas itérer sur la liste des propriétés d'objet. Habituellement, toutes les propriétés de l'objet ne doivent pas être sérialisées et les propriétés sérialisables ne sont pas égales.

abstract class parentClass implements JsonSerializable { 

    // You can remove this default implementation 
    // to force all children class implement the method 
    public function jsonSerialize() 
    { 
     return array(); 
    } 
} 

class childClass extends parentClass { 
    private $childField; 
    public $pubChildField; 

    public function jsonSerialize() 
    { 
     return array(
      'field1' => $this->childField, 
      'field2' => base64_encode($pubChildField), 
      // etc ... 
     ); 
    } 
} 

var_dump((new Child())->jsonSerialize()); 

Essayez d'écrire du code plus facile à lire et à comprendre. Vous allez vous remercier plus tard.