J'écrivais une classe qui utilise __get() et __set() pour stocker et récupérer des éléments de tableau dans un tableau maître. J'ai fait un chèque pour rendre certains éléments inoubliables, essentiellement pour recréer des propriétés privées. J'ai remarqué qu'il semblait que __get intercepte tous les appels aux propriétés de classe. Ça craint pour moi, parce que je voulais avoir une variable privée vers le monde extérieur (indisponible via get), mais j'essayais d'y accéder en référençant directement le tableau principal depuis l'intérieur de la classe. Bien sûr, le tableau de maître n'est pas dans la liste blanche des propriétés getTable :(Emule les propriétés publiques/privées avec __get() et __set()?
Est-il possible que je peux imiter les propriétés publiques et privées dans une classe php qui utilise __get() et __set()?
Exemple :
<?
abstract class abstraction {
private $arrSettables;
private $arrGettables;
private $arrPropertyValues;
private $arrProperties;
private $blnExists = FALSE;
public function __construct($arrPropertyValues, $arrSettables, $arrGettables) {
$this->arrProperties = array_keys($arrPropertyValues);
$this->arrPropertyValues = $arrPropertyValues;
$this->arrSettables = $arrSettables;
$this->arrGettables = $arrGettables;
}
public function __get($var) {
echo "__get()ing:\n";
if (! in_array($var, $this->arrGettables)) {
throw new Exception("$var is not accessible.");
}
return $this->arrPropertyValues[$var];
}
public function __set($val, $var) {
echo "__set()ing:\n";
if (! in_array($this->arrSettables, $var)) {
throw new Exception("$var is not settable.");
}
return $this->arrPropertyValues[$var];
}
} // end class declaration
class concrete extends abstraction {
public function __construct($arrPropertyValues, $arrSettables, $arrGettables) {
parent::__construct($arrPropertyValues, $arrSettables, $arrGettables);
}
public function runTest() {
echo "Accessing array directly:\n";
$this->arrPropertyValues['color'] = "red";
echo "Color is {$this->arrPropertyValues['color']}.\n";
echo "Referencing property:\n";
echo "Color is {$this->color}.\n";
$this->color = "blue";
echo "Color is {$this->color}.\n";
$rand = "a" . mt_rand(0,10000000);
$this->$rand = "Here is a random value";
echo "'$rand' is {$this->$rand}.\n";
}
}
try {
$objBlock = & new concrete(array("color"=>"green"), array("color"), array("color"));
$objBlock->runTest();
} catch (exception $e) {
echo "Caught Exeption $e./n/n";
}
// no terminating delimiter
$ php test.php
Accessing array directly:
__get()ing:
Caught Exeption exception 'Exception' with message 'arrPropertyValues is not accessible.' in /var/www/test.php:23
Stack trace:
#0 /var/www/test.php(50): abstraction->__get('arrPropertyValu...')
#1 /var/www//test.php(68): concrete->runTest()
#2 {main}.
Mais il y a encore un problème - puisque je suis stocker tout un tableau, 'getPriv()' a faire référence à la valeur dans la propriété de classe '$ arrPropertyValues', qui est interceptée par' __get() '... boucle infinie? – user151841
Je serai sacrée! Ça marche! Mais pourquoi? Est-ce parce que '__get()' n'intercepte pas dans la classe d'origine? – user151841
@user Il intercepte dans la classe d'origine - donc à l'intérieur de la classe vous devriez appeler 'getPriv'. Je ne suis pas sûr de vous avoir compris, mais '__get' n'intercepte pas les appels de méthode ou l'accès aux propriétés si les propriétés sont explicitement déclarées. – Artefacto