8791 sujets

Développement web côté serveur, CMS

Bonjour !

J'ai un problème que je n'arrive pas à régler en rapport avec la programmation orienté objet de PHP. Je vais essayer d'exposer mon problème clairement.

J'ai deux class (objets):

1- DatabaseObject:
Qui est ma classe de base à partir de laquelle je crée d'autres objets qui s'y réfèrent pour plusieurs fonctions communes (ajouter à la DB, mettre à jour ses infos, etc)

2- User :
Qui est mon objet utilisateur

Puisque plusieurs objets découlent de DatabaseObject, j'ai en son sein une fonction qui permet de mettre à jour les informations des différents objets. Tous ces objets n'ayant pas les mêmes champs MySQL, je me réfère à un array() déclaré dans chaque objet enfant sur lequel je boucle pour récupérer mes champs.

Voilà un exemple (fonction déclaré dans DatabaseObject):


    protected function attributes(){
        $attributes = array();
        foreach(static::$db_fields as $field){
            if(property_exists($this, $field)){
                $attributes[$field] = $this->$field;
            }
        }
        return $attributes;
    }


J'appelle le tableau des valeurs MySQL par la déclaration static::$db_fields. Jusque là tout va bien, mais j'aimerais que $db_fields soit variable et qu'il puisse être modifié dans une fonctions de l'enfant, et être repris sous sa forme modifié lorsque utilisé par une fonction hérité de son parent.

Cependant, les autres techniques pour cibler une variable propre à l'instance seraient normalement (par exemple)


$this->db_fields

// ou

self::$db_fiels


Mais ces deux méthodes ne prennent qu'en compte l'object actuel (soit DatabaseObject), peu importe qu'un enfant ait appelé la fonction hérité de son parent. (ce qui est un bug de PHP 5.2)

Le mot clé static:: vient normalement corriger ce problème, mais encore il n'est pas parfait puisqu'il fait seulement référence à la classe Enfant - et non à ses itérations (et donc à $db_fields tel que déclaré par défaut dans la classe - et non à la valeur modifié d'une instance)...

J'imagine, j'espère, qu'il y a une solution simple pour pallier à ce problème..?

(Je peux tenter de ré-expliquer si ce n'était pas suffisamment clair)
Modifié par Vaxilart (27 Jul 2011 - 16:56)
Salut,

En utilisant un attribut membre et le paramétrant dans le constructeur:

/*abstract?*/ class DatabaseObject{
  protected: $db_fields;

  protected function __construct($db_fields = array()){
    $this->db_fields = $db_fields;
  }

    protected function attributes(){
        $attributes = array();
        foreach(static::$db_fields as $field){
            if(property_exists($this, $field)){
                $attributes[$field] = $this->$field;
            }
        }
        return $attributes;
    }
…
}

class DataObjectA extends DataBaseObject{
  public function __construct(){
    parent::__construct(array('truc'->'much'));
  }
…
}

class DataObjectB extends DataObjectA{
  public function __construct(){
    parent::__construct();
    $this->db_fields['bidule'] = 'machin';
  }
…
}


Puis un p'tit singleton pour n'avoir qu'une seule instance, mais pas sûr d'avoir comprit le problème Smiley ohwell .
Salut,

Finalement j'ai fait à peu près comme ça.

Et ça a plutôt bien marché. Je crois que hier j'étais trop fatigué et que je me suis simplement gouré dans la logique de mon code en essayant cette solution Smiley langue