Question

When trying to change it,throw an exception.

Was it helpful?

Solution

I suppose a solution, for class properties, would be to :

  • not define a property with the name that interests you
  • use the magic __get method to access that property, using the "fake" name
  • define the __set method so it throws an exception when trying to set that property.
  • See Overloading, for more informations on magic methods.

For variables, I don't think it's possible to have a read-only variable for which PHP will throw an exception when you're trying to write to it.


For instance, consider this little class :

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
        }
    }
}

Instanciating the class and trying to read the property :

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

Will get you the expected output :

test

While trying to write to the property :

$a->myVar = 10;

Will get you an Exception :

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

OTHER TIPS

class test {
   const CANT_CHANGE_ME = 1;
}

and you refer it as test::CANT_CHANGE_ME

Use a constant. Keyword const

I know this is an old question, but PASCAL's answer really helped me and I wanted to add to it a bit.

__get() fires not only on nonexistent properties, but "inaccessible" ones as well, e.g. protected ones. This makes it easy to make read-only properties!

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;
        }
    }
}

The short answer is you can't create a read-only object member variable in PHP.

In fact, most object-oriented languages consider it poor form to expose member variables publicly anyway... (C# being the big, ugly exception with its property-constructs).

If you want a class variable, use the const keyword:

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

This variable can be accessed:

echo MyClass::myVariable;

This variable will exist in exactly one version regardless of how many different objects of type MyClass you create, and in most object-oriented scenarios it has little to no use.

If, however, you want a read-only variable that can have different values per object, you should use a private member variable and an accessor method (a k a getter):

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

The variable is set in the constructor, and it's being made read-only by not having a setter. But each instance of MyClass can have its own value for 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top