Il existe différents ORM en PHP ( Doctrine, PHPMyObject, ... ) mais après jetté un oeil sur leur façon de fonctionner je me rends compte que ceux-ci violent les principes fondamentaux de la programmation orientée objet.
En effet, lorsqu'il s'agit d'initialiser les attributs d'une instance d'une classe, les classes de mapping accèdent directement aux membres de la classe à mapper qui doivent être déclarés publiques ou bien énumérés dans un tableau qui lui sera déclaré publique.
Au contraire, en java, Hibernate à la possibilité d'accéder directement aux membres déclarés private ou protected d'une classe lors du mapping, ce qui à ma connaissance, n'existe pas en PHP.
Je suis à la recherche d'un pattern qui permettrait à une classe de ne donner accès à ses attributs private ou protected qu'à une classe de mapping donnée. J'ai imaginé le code suivant :
Code : Tout sélectionner
interface MappedObject{
//retourne la map qui décrit les propriétés de l'objet et leur emplacement dans la bdd
public function Map getMap();
//donner accès aux attributs privés à la classe de mapping
public function setDataMemberAccess( Mapper &$mapper, $dataMember );
}
Code : Tout sélectionner
class User implements MappedObject{
private $id;
private $login;
public function __construct( $id ){ $this->id = intval( $id ); }
public function getMap(à{ return new UserMap(); }
public function setDataMemberAccess( Mapper &$mapper, $dataMember ){
//l'attribut privé sera récupéré par référence par le mappeur,
//je n'ai pas testé si cela était possible
$mapper->setCurrentDataMember( $this->$dataMember );
}
}
Code : Tout sélectionner
class Mapper{
//récupérer une référence vers l'attribut privé de la classe à mapper
//aucune idée si cela fonctionne
public function setCurrentDataMember( &$dataMember ){
$this->currentDataMember = $dataMember;
}
public function map( $instance ){
$map = $instance->getMap();
//pour chaque attributs définit dans la map on récupère la valeur dans la bdd
//et on inititalise l'attribut de la classe
foreach( ....as $dataMember => $value ){
$instance->setDataMemberAccess( $this, $dataMember ); //récupérer l'accès
$this->currentDataMember = $value; //initialiser
}
}
}
Code : Tout sélectionner
$user = new User( 1 );
$mapper = new Mapper();
$mapper->map( $user );