12
votes

Propriétés en lecture seule en PHP?

Y a-t-il un moyen de faire une propriété en lecture seule d'un objet en PHP? J'ai un objet avec un couple de tableaux dedans. Je veux y accéder comme je serais normalement un tableau xxx

mais je ne veux pas pouvoir écrire à ces tableaux après leur constriction. Il se sent comme un pitaine de construire une variable locale: xxx

et de toute façon, alors qu'il empêche le tableau de l'objet vierré, cela ne m'empêche pas de ré-écrire variable de tableau locale.


0 commentaires

4 Réponses :


3
votes

2 commentaires

Boss: "Je pensais que tu as dit avoir terminé ton algorithme" Client: "J'ai fait le patron, quel est le problème" patron: "Cela ne fonctionne pas" Client: "Cela fonctionne en fonction de ce dont vous avez besoin"


@Chris Pourquoi le client prend-il des commandes du patron? MDR.



4
votes

Si défini, les fonctions magiques __ get () code> et __ ensemble () code> seront appelés chaque fois qu'une propriété non existante ou privée est accessible. Ceci peut être utilisé pour créer des méthodes "GET" et "Définir" pour les propriétés privées, et par exemple, faites-les les rendre en lecture seule ou à manipuler les données lorsqu'elles sont stockées ou récupérées.

Par exemple: P>

class Foo
{
  private $bar = 0;
  public $baz = 4; // Public properties will not be affected by __get() or __set()
  public function __get($name)
  {
    if($name == 'bar')
      return $this->bar;
    else
      return null;
  }
  public function __set($name, $value)
  {
    // ignore, since Foo::bar is read-only
  }
}

$myobj = new Foo();
echo $foo->bar; // Output is "0"
$foo->bar = 5;
echo $foo->bar; // Output is still "0", since the variable is read-only


1 commentaires

Je recommanderais de jeter une exception dans définir si vous n'êtes pas autorisé à définir une variable particulière. La raison en est que sinon, cela peut être assez déroutant lorsque quelqu'un de nouveau doit faire quelque chose, et cela ne fonctionne pas. "Mais j'ai défini ce tableau pour inclure cette variable. L'affectation réussit, alors pourquoi le * # @ $ pas ne fonctionne pas?" ...



25
votes

Eh bien, la question est de savoir où voulez-vous empêcher l'écriture?

La première étape consiste à rendre la matrice protégée ou privée pour empêcher l'écriture de l'extérieur de la portée de l'objet: p> xxx pré>

si de "extérieur" de la matrice, un getter sera Vous allez bien? Soit: p> xxx pré>

et l'accès comme p> xxx pré>

ou p> xxx pré> p> et l'accès comme: p> xxx pré>

Notez qu'ils ne renvoient pas de références. Vous ne pouvez donc pas changer le tableau d'origine de l'extérieur de l'objet de l'objet. Vous pouvez modifier la matrice elle-même ... p>

Si vous avez vraiment besoin d'une matrice entièrement immuable, vous pouvez utiliser un objet en utilisant arrayaccess code> ... p>

ou, vous pouvez simplement prolonger ArrayObject code> et écrase toutes les méthodes d'écriture: P>

$newArray = $this->arrArray->getArrayCopy();
//Edit array here
$this->arrArray = new ImmutableArrayObject($newArray);


2 commentaires

Si je veux que mon réseau immuable se charge elle-même avec des données sur la création, je écrase la fonction __Construction, appelez le constructeur parent, mais comment puis-je définir ce que l'objet contient?


Très bonne réponse! Mais remarquez qu'un tableau peut contenir des objets: chaque objet est renvoyé comme une référence et peut être modifié, même avec votre classe immuable: $ A = nouvel immutableArrayRayObject ((objet) ['FOO' => 'BAR']) ; $ b = $ a [0]; $ b-> foo = 'changé';



0
votes

Dans la classe, faites ceci:

$obj->set_array($new_array);


0 commentaires