2010-07-10 6 views
3

Suite "problème"PHP getter/setter au tableau

PHP Classe avec beaucoup de propertys. Beaucoup de Getters/Setter.

Existe-t-il une bonne solution pour convertir tous les propertys en tableau?

protected $name; 
protected $date; 

public function getName(); 
public function getDate(); 
public function asArray(); // call all getters? 
+0

posez-vous des questions sur une classe intégrée, un code de bibliothèque ou le vôtre? – Kris

Répondre

9

Votre API déjà définie et vous êtes coincé avec des méthodes GetX et setX? Je préfère de beaucoup les propriétés. Moins de typage, une meilleure distinction entre les propriétés et les méthodes, et le code résultant ressemble plus à PHP et moins à Java. Mais exposer les propriétés ne signifie pas que vous perdez l'encapsulation et que tous vos internals deviennent publics. Avec les méthodes magiques __get et __set, vous pouvez avoir un contrôle très précis sur ce que vous présentez. De plus, il serait plutôt trivial pour vider les propriétés comme un tableau:

class Foo 
{ 
    protected $properties; 

    public function __construct() { 
     $this->properties = array(); 
    } 

    public function __set($prop, $value) { 
     $this->properties[$prop] = $value; 
    } 

    public function __get($prop) { 
     return $this->properties[$prop]; 
    } 

    public function toArray() { 
     return $this->properties; 
    } 
} 

Hélas, si vous êtes coincé avec setters/getters à cause d'un patron de mauvaise humeur ou une mauvaise compréhension de ce POO doit être, pourquoi pas simplement cast l'objet à un tableau?

class Bar 
{ 
    public $x; 
    public $y; 
    public $z; 
    protected $a; 
    protected $b; 
    protected $c; 
    private $q; 
    private $r; 
    private $s; 

    public function __construct() { 
    } 

    public function setA($value) { 
     $this->a = $value; 
    } 

    public function getA() { 
     return $this->a; 
    } 

    public function setB($value) { 
     $this->b = $value; 
    } 

    public function getB() { 
     return $this->b; 
    } 

    public function setC($value) { 
     $this->c = $value; 
    } 

    public function getC() { 
     return $this->c; 
    } 

    public function toArray() { 
     return (array)$this; 
    } 
} 

Remarquez comment public protégé, et les propriétés privées sont exprimés:

$bar = new Bar(); 
print_r($bar->toArray()); 

array(9) { 
    ["x"]=> 
    NULL 
    ["y"]=> 
    NULL 
    ["z"]=> 
    NULL 
    [" * a"]=> 
    NULL 
    [" * b"]=> 
    NULL 
    [" * c"]=> 
    NULL 
    [" Foo q"]=> 
    NULL 
    [" Foo r"]=> 
    NULL 
    [" Foo s"]=> 
    NULL 
} 

Notez que les clés du tableau de/privé protégées ne commencent pas par un espace, il est une valeur nulle. Vous pouvez les retaper ou même filtrer les propriétés protégées/privé si vous aimez:

public function toArray() { 
    $props = array(); 
    foreach ((array)$this as $key => $value) { 
     if ($key[0] != "\0") { 
      $props[$key] = $value; 
     } 
    } 
    return $props; 
} 

Vous travaillez avec un langage dynamique; profitez-en et profitez-en!

+2

+1 pour l'approche typecast. Je ne suis pas d'accord avec l'utilisation abusive de __get/__ pour getter/setters cependant. – Gordon

0

Une option serait de créer un tableau dans votre constructeur. Vous aurez un getter et un setter .. Lorsque vous souhaitez définir ou obtenir quelque chose, faire quelque chose comme:

$foo->get('UID'); //(to get user id) 
or 
$foo->set('UID', 5); // to set something) 
3

Comment l'utilisation ReflectionClass et ReflectionMethod, quelque chose comme ceci:

class PropertyHolder 
{ 
    private $name; 
    private $date; 
    private $anotherProperty; 

    public function __construct($name, $date) 
    { 
     $this->name = $name; 
     $this->date = $date; 
    } 

    public function getName() 
    { 
     return $this->name; 
    } 

    public function getDate() 
    { 
     return $this->date; 
    } 

    public function asArray() 
    { 
     $result = array(); 

     $clazz = new ReflectionClass(__CLASS__); 
     foreach ($clazz->getMethods() as $method) { 
      if (substr($method->name, 0, 3) == 'get') { 
       $propName = strtolower(substr($method->name, 3, 1)) . substr($method->name, 4); 

       $result[$propName] = $method->invoke($this); 
      } 
     } 

     return $result; 
    } 
+0

+ 1 Vous m'avez battu à une solution presque identique par seulement quelques secondes :-) – Mike

2

Un (array) simple, monter $this suffit:

public function toArray() { 
    $array = (array) $this; 
    unset($array['private'], $array['privateagain']); 
    return $array; 
} 
:

(array) $this; 

Si vous avez ces propriétés supplémentaires (privés, par exemple, qui ne doit pas être ed toArray()) vous pouvez par la suite désinitialiser