How to implement a read-only member variable in PHP?

php readonly property
php getters and setters
php __get
php class variable scope

When trying to change it,throw an exception.

Read-only object variables in php using magic methods, You can create read-only object variables by using the "private" keyword and the __get() and __set() magic methods like this: $varName;  PHP 5 is very very flexible in accessing member variables and member functions. These access methods maybe look unusual and unnecessary at first glance; but they are very useful sometimes; specially when you work with SimpleXML classes and objects.

class test {
   const CANT_CHANGE_ME = 1;
}

and you refer it as test::CANT_CHANGE_ME

PHP: Read Only Attributes, Just like in JavaScript, many PHP developers find themselves in Unfortunately, the most common practice is to use a pseudo getter (again, like an object instance, but which is invoked in certain specific situations instead. chelmertz. iamnearlythere.com. Member for 11 years, 4 months. 14 How to implement a read-only member variable in PHP? Feb 26 '10. View all questions and answers →

Use a constant. Keyword const

Request #46506 :: readonly attribute for (public) class variables, Request #46506, readonly attribute for (public) class variables to create classes with public variables that are readonly and can only be written __get and __set work horribly with, for instance, PhpStorm, arguably the best  PHP allows member variables and functions to be declared as static using the static keyword. As we have shown in our examples so far, normal member variables are independent from object to object. In contrast, static member variables are shared across all instances of a class.

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

Properties - Manual, Class member variables are called "properties". PHP 5 will still accept the use of the keyword var in property declarations instead of (or in addition to) public,  PHP allows you to use dynamic variable names, called variable variables. You can name a variable with the value stored in another variable. That is, one variable contains the name of another variable.

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

Variable scope - Manual, For the most part all PHP variables only have a single scope. are the result of expressions, but you can't use any function here, what will cause a parse error. Otherwise, there's no way that satisfies your restrictions (short of hooking function calls in PHP through an extension, but even then you'd need to change your static variable accesses to function calls; otherwise, you'd have to patch PHP). Of course, it's highly doubtful that what your application is doing is good design.

Visibility - Manual, Members declared protected can be accessed only within the class itself and by Note: The PHP 4 method of declaring a variable with the var keyword is still This is because the implementation specific details are already known when  It’s needed to take a variable across several scripts to implement specific functionalities of the system. Properties of a PHP variable: A variable name must start with a letter or the underscore character. A variable name cannot start with a number. A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ )

rfc:propertygetsetsyntax, Properties do not even have to be associated with a class member, and This way, someone using the class can only read or “get” the variable, but not write Read-only property #1 property MyHours1 extends Hours { use  Properties. You learned from the previous chapter that private variables can only be accessed within the same class (an outside class has no access to it). However, sometimes we need to access them - and it can be done with properties. A property is like a combination of a variable and a method, and it has two methods: a get and a set method:

ReflectionProperty - Manual, ReflectionProperty implements Reflector { Read-only, throws ReflectionException in attempt to write. class In your example, $a->foo is a dynamic member - it is not defined as a member of class, //serialize static properties (class variable) If a function/method parameter has a type declaration , then php compiler will check it the moment of invocation regardless if strict_types is set to 1 or 0 or not set at all. However, php will check parameters types on build in php functions when strict_types is set to 1;

Comments
  • Good answer!BTW,what's __call used for?
  • __call is called when you're trying to call a method that doesn't exit in the class (like __get is called when you're trying to read a property that doesn't exist in the class) -- see fr2.php.net/manual/en/…
  • @Pascal MARTIN ,thanks!I also know that you are an experienced user of symfony/doctrine,can you take a look at this post:stackoverflow.com/questions/2339800/… ?
  • You're welcome :-) ;;; Symfony ? hu, I have never really used Symfony -- I might be more of a ZF user ;;; Oh, that question is about Doctrine, I seen, and not Symfony ;;; and I've never used trees with Doctrine yet -- sorry...
  • Oh,that's fine.What about this one:stackoverflow.com/questions/2331723/… really having a hard time converting sql to YAML,especially the local/foreign settings in relation part..
  • How will you throw a customized exception?
  • @user198729 Why would you want to throw a customized exception?
  • And if I want two instances of test with two different values for CANT_CHANGE_ME? This is a class variable, not a member and it will exist only in one copy...
  • @Erk you could hide the value behind a method in an interface, and implement that interface in all classes that should have a different value. That goes both for a "set once" member that is probably requested by this question, or something that's defined before run-time.