Pergunta

Ao tentar alterá-lo, lance uma exceção.

Foi útil?

Solução

Suponho que uma solução, para propriedades de classe, seria::

  • não definir uma propriedade com o nome que lhe interessa
  • Use a magia __get Método para acessar essa propriedade, usando o nome "falso"
  • Defina a __set Método, portanto, ele lança uma exceção ao tentar definir essa propriedade.
  • Ver Sobrecarga, para mais informações sobre métodos mágicos.

Para variáveis, não acho que seja possível ter uma variável somente leitura para a qual o PHP lançará uma exceção quando você estiver tentando escrever para ela.


Por exemplo, considere esta pequena classe:

class MyClass {
    protected $_data = array(
        'myVar' => 'test'
    );

    public function __get($name) {
        if (isset($this->_data[$name])) {
            return $this->_data[$name];
        } else {
            // non-existant property
            // => up to you to decide what to do
        }
    }

    public function __set($name, $value) {
        if ($name === 'myVar') {
            throw new Exception("not allowed : $name");
        } else {
            // => up to you to decide what to do
        }
    }
}

Instanciando a aula e tentando ler a propriedade:

$a = new MyClass();
echo $a->myVar . '<br />';

Vai obter a saída esperada:

test

Enquanto tenta escrever para a propriedade:

$a->myVar = 10;

Terá uma exceção:

Exception: not allowed : myVar in /.../temp.php on line 19

Outras dicas

class test {
   const CANT_CHANGE_ME = 1;
}

e você o refere como test::CANT_CHANGE_ME

Use uma constante. Palavra -chave const

Eu sei que esta é uma pergunta antiga, mas a resposta do PASCAL realmente me ajudou e eu queria acrescentar um pouco.

__get() dispara não apenas em propriedades inexistentes, mas também em propriedades "inacessíveis", por exemplo.os protegidos.Isso facilita a criação de propriedades somente leitura!

class MyClass {
    protected $this;
    protected $that;
    protected $theOther;

    public function __get( $name ) {
        if ( isset( $this->$name ) ) {
            return $this->$name;
        } else {
            throw new Exception( "Call to nonexistent '$name' property of MyClass class" );
            return false;
        }
    }

    public function __set( $name ) {
        if ( isset( $this->$name ) ) {
            throw new Exception( "Tried to set nonexistent '$name' property of MyClass class" );
            return false;
        } else {
            throw new Exception( "Tried to set read-only '$name' property of MyClass class" );
            return false;
        }
    }
}

A resposta curta é que você não pode criar uma variável de membro de objeto somente leitura em PHP.

Na verdade, a maioria das linguagens orientadas a objetos considera uma forma inadequada expor publicamente as variáveis-membro de qualquer maneira...(C# sendo a grande e feia exceção com suas construções de propriedades).

Se você quiser uma variável de classe, use o const palavra-chave:

class MyClass {
    public const myVariable = 'x';
}

Esta variável pode ser acessada:

echo MyClass::myVariable;

Esta variável existirá em exatamente uma versão, independentemente de quantos objetos diferentes do tipo MyClass você cria e, na maioria dos cenários orientados a objetos, tem pouca ou nenhuma utilidade.

Se, no entanto, você deseja uma variável somente leitura que possa ter valores diferentes por objeto, você deve usar uma variável de membro privada e um método acessador (também conhecido como getter):

class MyClass {
    private $myVariable;
    public function getMyVariable() {
        return $this->myVariable;
    }
    public function __construct($myVar) {
        $this->myVariable = $myVar;
    }
}

A variável é definida no construtor e se torna somente leitura por não ter um setter.Mas cada instância de MyClass pode ter seu próprio valor para myVariable.

$a = new MyClass(1);
$b = new MyClass(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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top