Salut,
Je vois pas mal de réponses mais aucun code, alors je vais coller mon code pour que vous puissiez me dire si je fais les choses correctement

et qui sait, si je vais bien les choses peut être que colibri aura un réponse un peu plus colorée
Voici ma classe de base:
class Entity
{
# Fields
protected $_id;
protected $_isSaved;
# Universal getter and setter
// Derived classes should override the setter for read-only properties
public function __get( $propertyName )
{
// converts Property into _property
$fieldName = '_' . strtolower( substr( $propertyName, 0, 1 ) ) . substr( $propertyName, 1 );
if( property_exists( $this, $fieldName ) )
return $this->$fieldName;
else
throw new Exception( 'Unknow property ' . $propertyName );
}
public function __set( $propertyName, $value )
{
// converts Property into _property
$fieldName = '_' . strtolower( substr( $propertyName, 0, 1 ) ) . substr( $propertyName, 1 );
switch( $fieldName )
{
// The following has been commented out because Id needs to be settable from outside.
// Normally it should be internally settable, so the manager class which is in the
// same namespace is able to modify it, but the internal keyword doesn't exists in
// PHP, therefore we simply make it public.
// case '_id':
// throw new Exception( 'Property Id is read-only' );
// break;
case '_isSaved':
$this->_isSaved = $value;
break;
default:
if( property_exists( $this, $fieldName ) )
{
if( $this->$fieldName != $value )
{
$this->$fieldName = $value;
$this->ModifyEntity();
}
}
else
throw new Exception( 'Unknow property ' . $attribute );
break;
}
}
# Constructors
public function __construct()
{
$numArgs = func_num_args();
$args = func_get_args();
if( $numArgs == 0 )
call_user_func_array( array( $this, '__constructNewEntity' ), null );
else
call_user_func_array( array( $this, '__constructExistingEntity' ), $args );
}
private function __constructNewEntity()
{
$this->_id = -1;
$this->_isSaved = false;
}
private function __constructExistingEntity( $id )
{
// Because of this all classes that derive from this one should have their ID
// property set first in the list of arguments
$this->_id = $id;
$this->_isSaved = true;
}
# Private Methods
private function ModifyEntity()
{
$this->_isSaved = false;
}
}
La classe contient:
- une propriété ID qui sera égal à l'ID sauvée dans la DB, ou alors -1 si l'objet n'a pas encore été sauvé dans la DB
- une propriété isSaved, qui me permet de savoir si oui ou non l'objet a été sauvé dans la DB
- un getter universel que les classe dérivée pourront utiliser, en 2 mots elle me permet d'appeler $[Object]->[Propriété] et la classe cherchera automatiquement une propriété sous la forme "_propriété" qui correspond, la raison est que je viens du C# et que je n'aime pas avoir des methods pour aller chercher les valeurs de mes proriétés
- un setter universel qui doit etre overridé pour les propriétés read only
- 3 constructeurs, 1 de base qui défini le prochain à appeler, 1 qui construit un nouvel objet et 1 qui construit un objet qui a été fetché de la DB.
Et voici une classe qui dérive de ma classe de base:
class Reference extends Entity
{
# Fields
// In order for the base class to have access to those properties they should all be
// declared as protected
protected $_name;
protected $_email;
protected $_company;
protected $_position;
protected $_message;
protected $_password;
protected $_createdAtGmt;
protected $_deletedAtGmt;
# Universal setter
public function __set( $propertyName, $value )
{
// converts Property into _property
$fieldName = '_' . strtolower( substr( $propertyName, 0, 1 ) ) . substr( $propertyName, 1 );
switch( $fieldName )
{
case '_createdAtGmt':
throw new Exception( 'Property CreatedAtGmt is read-only' );
break;
case '_deletedAtGmt':
throw new Exception( 'Property DeletedAtGmt is read-only' );
break;
default:
$args = func_get_args();
call_user_func_array( array( $this, 'parent::__set' ), $args );
break;
}
}
# Constructors
public function __construct()
{
$num = func_num_args();
$args = func_get_args();
switch( $num )
{
case 0:
call_user_func_array( array( $this, 'parent::__construct' ), null );
call_user_func_array( array( $this, '__constructNewReference' ), null );
break;
case 9:
call_user_func_array( array( $this, 'parent::__construct' ), $args );
call_user_func_array( array( $this, '__constructExistingReference' ), $args );
break;
default:
throw new Exception( 'Number of arguments invalid' );
}
}
private function __constructNewReference()
{
$this->_name = '';
$this->_email = '';
$this->_company = '';
$this->_position = '';
$this->_message = '';
$this->_password = '';
$this->_createdAtGmt = gmdate( 'Y-m-d H:i:s' );
$this->_deletedAtGmt = null;
}
private function __constructExistingReference(
$id, // Still present in the list of arguments but ignored by this constructor
$name,
$email,
$company,
$position,
$message,
$password,
$createdAtGmt,
$deletedAtGmt )
{
$this->_name = $name;
$this->_email = $email;
$this->_company = $company;
$this->_position = $position;
$this->_message = $message;
$this->_password = $password;
$this->_createdAtGmt = $createdAtGmt;
$this->_deletedAtGmt = $deletedAtGmt;
}
}
Cette classe contient:
- pas mal de propriétés, toutes accessible via le setter universel de la classe de base, je peux donc appeler $ref->Company pour obtenir la valeur sauvé dans $_company
- un override du setter universel qui défini que 2 de mes propriétés sont read only, et appel le setter universel de base pour les autres
- et encore une fois 3 constructeurs, 1 qui appel le constructeur de base et défini le prochain à appeler, 1 pour les nouveaux objets et 1 pour les objets fetchés de la DB
Voilà pour mon "architecture" qu'en pensez-vous?