
Réaliser un Bean en PHP
Vous êtes ici : Accueil
/ Articles
/ Formations en PHP
Qu’est-ce qu’un Bean ?
Un Bean est une classe devant respecter les conditions suivantes :
Chaque propriété est en private
Chaque propriété possède un accesseur et un manipulateur
Le Bean doit posséder un constructeur sans argument.
Implémentation explicite
Voici une première implémentation en PHP, de manière explicite. L’avantage de cette syntaxe est la lisibilité. En revanche, pour chaque Bean, il est nécessaire de redéfinir toutes les méthodes, ce qui est fastidieux :
<?php
class HumanBean {
private $first_name;
private $last_name;
public function setFirstName( $first_name ) {
$this->first_name = $first_name;
}
public function setLastName( $last_name ) {
$this->last_name = $last_name;
}
public function getFirstName( $first_name ) {
return $this->first_name;
}
public function getLastName( $last_name ) {
return $this->last_name;
}
}
?>
Une solution générique
PHP, à la différence de Java, permet de définir des propriétés et méthodes "à la volée", grâce à sa réflexivité. Nous allons donc définir une classe parent Bean dont hériteront tous les beans. Pour cela, nous auront recours à la méthode suivante :
<?php
public function __call( $name, $args )
?>
Cette méthode est appelée lors de l’appel à une méthode n’existant pas. Ainsi, si nous créons une classe sans méthode et que nous tentons d’en appeler une, cette méthode sera appelée à la place, prenant en premier paramètre le nom de la méthode que l’on voulait appeler, et en second un tableau des arguments.
Exemple :
<?php
class SansMethode {
public function __call( $name, $args ) {
echo "
La méthode $name a été appelée";
}
}
$o = new SansMethode();
$o->setFirstName( '
Robert' );
?>
Nous auront également recours à une expression régulière toute simple pour remplacer la syntaxe setFirstName en first_name :
Nous allons nous créer 2 méthodes de test : isSetter et isGetter, pour différencier les manipulateurs des accesseurs :
<?php
class Bean {
private function isGetter( $name ) {
return substr( $name, 0, 3 ) == '
get';
}
private function isSetter( $name ) {
return substr( $name, 0, 3 ) == '
set';
}
}
?>
Pour ne pas pouvoir accéder aux propriétés - définies à la volée - de l’extérieur de la classe, nous allons les stocker dans une propriété privée sous forme de tableau :
<?php
class Bean {
private $prop =
array();
}
?>
Il ne nous reste plus qu’à définir la méthode __call :
<?php
class Bean {
private $prop =
array();
public function __call( $name, $args ) {
if( $this->isGetter( $name ) ) {
return $this->prop[ $this->toProperty( $name ) ];
}
else if( $this->isSetter( $name ) ) {
return $this->prop[ $this->toProperty( $name ) ] = $args[0];
}
}
private function isGetter( $name ) {
return substr( $name, 0, 3 ) == '
get';
}
private function isSetter( $name ) {
return substr( $name, 0, 3 ) == '
set';
}
private function toProperty( $name ) {
$str =
preg_replace( '
/[A-Z]/', '
_$0', $str );
$str =
strtolower( $str );
$str =
substr( $str, 4 );
}
}
?>
Nous pouvons désormais écrire le code suivant :
<?php
$b = new Bean();
$b->setFirstName( '
Robert' );
echo $b->getFirstName();
?>
L’avantage est que toute les classes qui hériteront de la classe Bean pourront utiliser cette syntaxe sans redéfinir les méthodes, donc les gains de productivité sont indéniables. En revanche, la lisibilité en est amoindrie.
Commentaires
Jérôme a dit le 28 août 2009
Au secours ! T’as raison ! C’est vraiment trop fastidieux ! ;) On se demande vraiment pourquoi on a inventé l’objet ! :) Franchement, on croit rêver !
Change ton IDE, t’auras plus à te creuser les méninges pour rien ! :) Finalement, je l’aime mon Visual Studio :)