Je suppose que une solution, pour les propriétés de la classe, ce serait :
pas définir une propriété avec le nom qui vous intéresse
utiliser la magie __get méthode pour accéder à la propriété, à l'aide de la "fake" nom
définir la __set méthode de sorte qu'il déclenche une exception lorsque vous tentez de définir la propriété.
Voir La surcharge, pour plus d'informations sur les méthodes magiques.
Pour les variables, je ne pense pas que c'est possible d'avoir une lecture seule variable pour laquelle PHP va générer une exception lorsque vous essayez d'écrire.
Par exemple, considérons cette petite classe :
classMyClass{protected $_data = array('myVar'=>'test');publicfunction __get($name){if(isset($this->_data[$name])){return $this->_data[$name];}else{//non-existant property//=> up to you to decide what to do}}publicfunction __set($name, $value){if($name ==='myVar'){thrownewException("not allowed : $name");}else{//=> up to you to decide what to do}}}
Instanciating la classe et en essayant de lire la propriété :
$a =newMyClass();
echo $a->myVar .'<br />';
Permettra d'obtenir le résultat attendu :
test
Tout en essayant d'écrire à la propriété :
$a->myVar =10;
Vous obtiendrez une Exception :
Exception:not allowed : myVar in/.../temp.php on line 19
Bonne réponse!BTW,ce qui est __call? __call est appelée lorsque vous essayez d'appeler une méthode qui n'a pas de sortie dans la classe (comme __get est appelée lorsque vous essayez de lire une propriété qui n'existe pas dans la classe) - voir la section fr2.php.net/manual/en/... MARTIN ,merci!Je sais aussi que vous êtes un utilisateur expérimenté de symfony/doctrine,pouvez-vous jeter un oeil à ce post:stackoverflow.com/questions/2339800/... ? Vous êtes les bienvenus 🙂 ;;; Symfony ? hu, je n'ai jamais vraiment utilisé Symfony -- je suis peut-être plus d'une ZF utilisateur ;;; Oh, cette question est au sujet de la Doctrine, je l'ai vu, et pas de Symfony ;;; et je n'ai jamais utilisé les arbres avec la Doctrine pour l'instant, désolé... Oh,c'est très bien.Qu'en est celui-ci:stackoverflow.com/questions/2331723/... vraiment un moment difficile la conversion sql pour YAML,en particulier la local/foreign paramètres dans relation partie..
Comment allez-vous lancer une exception personnalisée? il ne sera pas levée d'une exception, mais une erreur d'analyse... Pourquoi voudriez-vous voulez pour lancer une exception personnalisée? Et si je veux les deux instances de test avec deux valeurs différentes pour CANT_CHANGE_ME? C'est une variable de classe, pas un membre et il n'existent qu'en un seul exemplaire... vous pouvez masquer la valeur derrière une méthode en une interface, et de mettre en œuvre cette interface dans toutes les classes qui doivent avoir une valeur différente. Qui va à la fois pour une "une seule fois" un membre qui est probablement demandé par cette question, ou quelque chose qui est défini avant le moment de l'exécution.
Je sais que c'est une vieille question, mais la réponse de PASCAL m'a vraiment aidé et je voulais ajouter un peu.
__get() se déclenche pas seulement sur inexistante propriétés, mais "inaccessible" ainsi, par exemple protégés. Cela rend plus facile pour faire les propriétés en lecture seule!
classMyClass{protected $this;protected $that;protected $theOther;publicfunction __get( $name ){if( isset( $this->$name )){return $this->$name;}else{thrownewException("Call to nonexistent '$name' property of MyClass class");returnfalse;}}publicfunction __set( $name ){if( isset( $this->$name )){thrownewException("Tried to set nonexistent '$name' property of MyClass class");returnfalse;}else{thrownewException("Tried to set read-only '$name' property of MyClass class");returnfalse;}}}
La réponse courte est que vous ne pouvez pas en créer un en lecture seule membre de l'objet variable en PHP.
En fait, la plupart des langages orientés objet considérer une mauvaise forme pour exposer les variables de membre public de toute façon... (C# étant le gros, laid exception avec sa propriété des constructions).
Si vous voulez une variable de classe, utilisez la const mot-clé:
classMyClass{publicconst myVariable ='x';}
Cette variable peut être consulté:
echo MyClass::myVariable;
Cette variable existe en une seule version indépendamment de la façon dont plusieurs différents objets de type MyClass vous créez, et dans la plupart orientée objet scénarios, il a peu ou pas d'utiliser.
Si, toutefois, vous voulez en lecture seule variable qui peut avoir des valeurs différentes par objet, vous devez utiliser une variable membre privée et d'une méthode d'accesseur (un k un getter):
La variable est définie dans le constructeur, et qu'il se fait en lecture seule à ne pas avoir un setter. Mais chaque instance de MyClass peut avoir sa propre valeur pour myVariable.
$a =newMyClass(1);
$b =newMyClass(2);
echo $a->getMyVariable();//1
echo $b->getMyVariable();//2
$a->setMyVariable(3);//causes an error - the method doesn't exist
$a->myVariable =3;//also error - the variable is private
Je suppose que une solution, pour les propriétés de la classe, ce serait :
__get
méthode pour accéder à la propriété, à l'aide de la "fake" nom__set
méthode de sorte qu'il déclenche une exception lorsque vous tentez de définir la propriété.Pour les variables, je ne pense pas que c'est possible d'avoir une lecture seule variable pour laquelle PHP va générer une exception lorsque vous essayez d'écrire.
Par exemple, considérons cette petite classe :
Instanciating la classe et en essayant de lire la propriété :
Permettra d'obtenir le résultat attendu :
Tout en essayant d'écrire à la propriété :
Vous obtiendrez une Exception :
__call
?__call
est appelée lorsque vous essayez d'appeler une méthode qui n'a pas de sortie dans la classe (comme__get
est appelée lorsque vous essayez de lire une propriété qui n'existe pas dans la classe) - voir la section fr2.php.net/manual/en/...MARTIN ,merci!Je sais aussi que vous êtes un utilisateur expérimenté de symfony/doctrine,pouvez-vous jeter un oeil à ce post:stackoverflow.com/questions/2339800/... ?
Vous êtes les bienvenus 🙂 ;;; Symfony ? hu, je n'ai jamais vraiment utilisé Symfony -- je suis peut-être plus d'une ZF utilisateur ;;; Oh, cette question est au sujet de la Doctrine, je l'ai vu, et pas de Symfony ;;; et je n'ai jamais utilisé les arbres avec la Doctrine pour l'instant, désolé...
Oh,c'est très bien.Qu'en est celui-ci:stackoverflow.com/questions/2331723/... vraiment un moment difficile la conversion sql pour YAML,en particulier la
local/foreign
paramètres dansrelation
partie..OriginalL'auteur Pascal MARTIN
et vous renvoyer comme
test::CANT_CHANGE_ME
il ne sera pas levée d'une exception, mais une erreur d'analyse...
Pourquoi voudriez-vous voulez pour lancer une exception personnalisée?
Et si je veux les deux instances de
test
avec deux valeurs différentes pourCANT_CHANGE_ME
? C'est une variable de classe, pas un membre et il n'existent qu'en un seul exemplaire...vous pouvez masquer la valeur derrière une méthode en une interface, et de mettre en œuvre cette interface dans toutes les classes qui doivent avoir une valeur différente. Qui va à la fois pour une "une seule fois" un membre qui est probablement demandé par cette question, ou quelque chose qui est défini avant le moment de l'exécution.
OriginalL'auteur chelmertz
Utiliser une constante. Mot-clé
const
OriginalL'auteur froadie
Je sais que c'est une vieille question, mais la réponse de PASCAL m'a vraiment aidé et je voulais ajouter un peu.
__get() se déclenche pas seulement sur inexistante propriétés, mais "inaccessible" ainsi, par exemple protégés. Cela rend plus facile pour faire les propriétés en lecture seule!
OriginalL'auteur Stephen R
La réponse courte est que vous ne pouvez pas en créer un en lecture seule membre de l'objet variable en PHP.
En fait, la plupart des langages orientés objet considérer une mauvaise forme pour exposer les variables de membre public de toute façon... (C# étant le gros, laid exception avec sa propriété des constructions).
Si vous voulez une variable de classe, utilisez la
const
mot-clé:Cette variable peut être consulté:
Cette variable existe en une seule version indépendamment de la façon dont plusieurs différents objets de type
MyClass
vous créez, et dans la plupart orientée objet scénarios, il a peu ou pas d'utiliser.Si, toutefois, vous voulez en lecture seule variable qui peut avoir des valeurs différentes par objet, vous devez utiliser une variable membre privée et d'une méthode d'accesseur (un k un getter):
La variable est définie dans le constructeur, et qu'il se fait en lecture seule à ne pas avoir un setter. Mais chaque instance de
MyClass
peut avoir sa propre valeur pourmyVariable
.OriginalL'auteur Erk