Variable protected générée à la volée

Signaler
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
-
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
-
Bonjour à vous :)

J'ai un petit soucis, je me demandais comment définir une variable à la volée dans une classe, sans qu'elle soit publique.

En code étant plus explicite :

class test {
    public function essai ($sVarName) {
        $this->$sVarName = "est affiché !";
    }
}

$o = new test ();
$o->essai ('try');

echo $o->try; // Affiche "est affiché !"

Moi je voudrais que la variable soit protected.
A savoir que je ne peux pas la définir dans "l'en tête" de la classe, puisque c'est l'utilisateur qui choisis le nom de la variable.
Existe-t-il une possibilité ? Si oui comment ?

Merci de votre aide :)

http://www.ReFlectiv.Net

8 réponses

Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
Hello,

stocke plutôt tes variables personnalisées dans un tableau qui lui, sera protégé.
<?php
class test {
    protected $aCustomVars;
   
    public function essai ($sVarName) {
        $this->aCustomVars[$sVarName] = "est affiché !";
    }
   
    public function __get($sProp) {
        if(array_key_exists($sProp, $this->aCustomVars)) {
            throw new Exception('Niet!');
        }
    }
}

$o = new test ();
$o->essai ('try');

echo $o->try;

?>
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
Mais le probleme c'est que (je l'ai pas dit tout à l'heure :p) la classe qui utilise la variable crée, est une classe qui étends la classe test. Du coup __get et __set ne fonctionne pas :/ (enfin d'apres mes tests !)

class test {
    public function essai ($sVarName) {
        $this->$sVarName = "est affiché !";
    }
}

class fille extends test {
    public function __construct () {

        $this->essai ('try');
        echo $this->try;

    }
}

Mon objectif n'est bien sur pas de mettre des simple strings, mais de pouvoir gerer des objets, dans ce cas, try aurait une instance d'une certaine classe

http://www.ReFlectiv.Net
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
Je ne comprends pas ton problème :
De tte manière, le __get() était juste là pour balancer l'exception. Enlève le, ça ne changera pas gd chose : tu n'auras pas ta variable. e principe est juste de stocker tes variables dans un tableau.
Parce que sinon, non, tu ne peux pas changer à la volée la visibilité d'une propriété. Ce serait un beau bordel.
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
Peut-etre qu'en détaillant plus, tu verra mon probleme :)

Tout d'abord, du code :

abstract class aController {
    public function load ($sPath, $sVarName) {
        $sPath = str_replace ('.', DIRECTORY_SEPARATOR, $sPath);
        if (!file_exists ($sPath))
            throw new Exception ('The file does not exists');
       
        include $sPath;
       
        $sClassName = substr ($sPath, strrpos ('.', $sPath));
       
        if (!class_exists ($sClassName))
            throw new Exception ('Invalid class name');
       
        $this->$sVarName = new $sClassName ();
    }
}

class Example extends aController {
    public function uneMethod () {
        $this->load ('Ma.Classe.De.Rss', 'rss');
        $this->load ('Db.Mysql', 'db');
       
        $this->db->open ('localhost', 'root', '');
        $this->db->selectDb ('exemple');
       
        $this->rss->display ($this->db->request ('SELECT * FROM rss'));
    }
}

Bon, c'est un example à l'arrache, mon framework est un peu mieux structuré ;) mais je pense que comme ca tu vois mieux la chose.

J'ai un gain de temps en faisant $this->db ensuite, plutot que de faire $this->MonTableau['db']->...

Voila mon probleme :) Ca marche, mais les propriétés sont publiques, alors que je les voudrais protected

Merci de ton aide :)

http://www.ReFlectiv.Net
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
Bah oui c'est un peu plus long à écrire mais bon...t'es un flemmard!
Tu peux tjrs passer par __call() en la rendant "protected" dans ce cas, mais c'est moins évident à gérer :
<?php
class oControler {
    protected $aContrl;
   
    public function load($sVar) {
        $this->aContrl[$sVar] = new $sVar;
    }
   
    protected function __call($oObj, array $args) {
        if(!array_key_exists($oObj, $this->aContrl)) {
            return false;
        }
        $method = array_shift($args);
        return $this->aContrl[$oObj]->$method($args);
    }
}

class test extends oControler {
    public function methode() {
        $this->load('B');
        return $this->B('truc');
    }
}

class A {
    public function truc() {
        return 'je suis A';
    }
}

class B {
    public function truc() {
        return 'je suis B';
    }
}

$a = new test;
$a->load('A');
echo $a->methode();

echo $a->A->truc();
?>

L'explication de $arg dans __call() : le 1er élément sera la méthode à appeler, et les suivants s'il y en a, les paramètres à passer à la méthode.
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
Ah ben non ça ne marche pas, si je rajoute ça dans le script :

echo $a->A('truc');
 La méthode est bien appelée. __call() fonctionne comme __get() ou __set() et ne tient pas compte de l'accessibilité (en tous cas à partir de php5.1 il me semble). C'est logique en fait. Par contre, là, ce n'est accessible qu'en lecture. Tu ne peux pas redéfinir les variables/objets hors du contexte de tes objets.
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
Donc si j'ai bien compris, c'est pas possible ?

Ahh tu vois que je suis pas un flemmard ;)

T'inquiète, j'avais essayé aussi diverses méthodes, mais aucune ne me convenait. Je vais garder la chose comme elle est actuellement. Je sais pas si c'est un bon point niveau sécurité, mais dès que je trouve une démarche pour la rendre protected, je te fait signe.

Merci de ton aide :)

http://www.ReFlectiv.Net
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
Bon je comprends pas.
Apres ton code, je me suis quand même posé la question, j'ai essayé un protected function __get ($sKey) pour retourner une valeur comprise dans un tableau d'objet privé, et ca marche, même dans une classe fille.
Ce qui me perturbe, c'est que j'avais essayé avant, et que ca marchais pas ... J'aurai jamais posé la question sans essayer :p

Donc bon bah ca marche :p

Merci bien de ton aide Maître ;)

http://www.ReFlectiv.Net