<?php
class maclasse
{
const ACCES_PRIVE = "Accès en %s à la propriété privée %s interdit";
private $_mavar; // Ce sera inaccessible
private $mavar2; // Ce sera en lecture seule
private $mavar3; // Ce sera en lecture/ecriture
/**
* Getter magique
*
* Retourne la valeur de la propriété uniquement si elle
* est mentionnée dans les accès autorisés en lecture
*/
public function __get($mavar)
{
$aLecture = array('mavar2', 'mavar3');
if (in_array ($mavar, $aLecture))
{
return ($this->{$mavar});
}
else
{
$erreur = sprintf (self::ACCES_PRIVE, 'lecture', $mavar);
throw new Exception ($erreur, E_USER_WARNING);
}
}
/**
* Setter magique
*
* Affecte la valeur à la propriété uniquement si elle
* est mentionnée dans les accès autorisés en écriture
*/
public function __set($mavar, $valeur)
{
$aEcriture = array('mavar3');
if (in_array ($mavar, $aEcriture))
{
$this->{$mavar} = $valeur;
}
else
{
$erreur = sprintf (self::ACCES_PRIVE, 'écriture', $mavar);
throw new Exception ($erreur, E_USER_WARNING);
}
}
}
J'utilise des tableaux dans lesquels je liste les propriétés auxquelles je permets un accès.Code : Tout sélectionner
private $__items;
private $globalHeight = 200;
private $globalWidth = 800;
private $globalBackgroundColor;
.... (il y en a un petit paquet)
public function __get ($var) { // $__ est privé, $_ est en lecture seule et $ est en lecture/ecriture, tous sont typés
if (substr($var,0,2) == '__') throw new Exception ("$var doesn't accept read action");
if (!isset($this->$var)) throw new Exception ("$var doesn't exists");
return $this->$var;
}
public function __set ($var,$value) {
if (substr($var,0,1) == '_') throw new Exception ("$var doesn't accept write action");
if (!isset($this->$var)) throw new Exception ("$var doesn't exists");
if (gettype($value) != gettype($this->$var)) throw new Exception ("$var doesn't accept casting");
if (is_object($value) && is_object($this->$var)) { if (get_class($value) != get_class($this->$var)) throw new Exception ("$var casting : " . get_class($this->$var) . " waited"); }
$this->$var = $value;
}
public function setMailTo (Mail $value)
{
// Mail is class Mail comme le type Url pour AS3, on peut écrire aussi : if (!$value instanceof Mail) throw ...
$this->mailTo = $value;
}
En PHP, ça sous-entend que ton paramètre doit être un objet de type Mail correspondant à une classe du même nom, et non une chaine.<?php
class maclasse
{
const ACCES_PRIVE = "Accès en %s à la propriété privée %s interdit";
const TYPE_INVALIDE = "La propriété %s doit être de type %s, la valeur reçue est invalide";
/**
* @var String
*/
private $mavar1;
/**
* @var Boolean
*/
private $mavar2;
/**
* @var Int
*/
private $mavar3;
/**
* Getter magique
*
* Retourne la valeur de la propriété uniquement si elle
* est mentionnée dans les accès autorisés en lecture
*/
public function __get($mavar)
{
$aLecture = array('mavar2', 'mavar3');
if (in_array ($mavar, $aLecture))
{
return ($this->{$mavar});
}
else
{
$erreur = sprintf (self::ACCES_PRIVE, 'lecture', $mavar);
throw new Exception ($erreur, E_USER_WARNING);
}
}
/**
* Setter magique
*
* Affecte la valeur à la propriété uniquement si elle
* est mentionnée dans les accès autorisés en écriture
* et que le type de valeur envoyé correspond au type attendu
*/
public function __set($mavar, $valeur)
{
$aEcriture = array(
'bool' => array('mavar2'),
'int' => array('mavar3')
);
if (in_array ($mavar, $aEcriture['bool']))
{
if(is_bool($valeur))
{
$this->{$mavar} = $valeur;
}
else
{
$erreur = sprintf (self::TYPE_INVALIDE, $mavar, 'booléen');
throw new Exception ($erreur, E_USER_WARNING);
}
}
elseif (in_array ($mavar, $aEcriture['int']))
{
if(is_int($valeur))
{
$this->{$mavar} = $valeur;
}
else
{
$erreur = sprintf (self::TYPE_INVALIDE, $mavar, 'entier');
throw new Exception ($erreur, E_USER_WARNING);
}
}
else
{
$erreur = sprintf (self::ACCES_PRIVE, 'écriture', $mavar);
throw new Exception ($erreur, E_USER_WARNING);
}
}
}
TU peux faire des variantes mais tu n'échapperas pas à la nécessité de valider les valeurs.
class maclasse
{
private $mavar1; //public
private $mavar2; //readonly
private $mavar3; //private
public function setMavar1($value)
{
$this->mavar1 = $value;
}
public function getMavar1()
{
return $this->mavar1;
}
public function getMavar2()
{
return $this->mavar1;
}
}
de tout façon même si on a 15 valeurs (et c'est rare) c'est que du copier coller et c'est plus claire, surtout niveau docCode : Tout sélectionner
public function setMailTo ($value) {
if (!is_string($value)) throw ...
if (!preg_match("/(mail)/",$value)) throw ...
$this->mailTo = $value;
}
Oui, au final, je m'étais trop basé sur C#. JAVA le fait, alors ... Le rajout d'appel Dynamique par __get et __set se serait un gadget. Je pense le mettre (Mes classes Graph sont des bacs à sable. J'essaie de faire un super code avec, et ils représentent des graphiques. Nul besoin de dire qu'il existe déjà d'excellentes bibliothèques pour ça ... mais c'est un très bon excercice).je m'embête pas moi, pas besoin de bidouille
de tout façon même si on a 15 valeurs (et c'est rare) c'est que du copier coller et c'est plus claire, surtout niveau docclass maclasse { private $mavar1; //public private $mavar2; //readonly private $mavar3; //private public function setMavar1($value) { $this->mavar1 = $value; } public function getMavar1() { return $this->mavar1; } public function getMavar2() { return $this->mavar1; } }