Nitin
Nitin

Reputation: 916

Set or define a value in constructor that cannot be changed afterwards (during runtime)

Is it possible to set or define a value in a class __construct() magic method that cannot be changed afterwards?

I am wondering if it is better for readability and in case of script injection attacks that some values like customer role and db creditentials can be fixed like class constants. Only in this case, the customer role and even db creditentials are defined after login.

Upvotes: 1

Views: 36

Answers (1)

bishop
bishop

Reputation: 39414

No, it is not possible at the language level. An RFC submitted in late 2014 proposed adding a readonly keyword to make a property immutable to consumers. The RFC had this to say:

There is currently no way to make a property readable to everyone and writeable only to the containing object, with PHP's visibility specifiers allowing all or nothing: a scope can either both read and write, or do neither. While __get and __set exist, these do not actually allow control of the same property, merely only exposing a separate property, and they are only usable for undeclared properties, which cannot be reflected and are not performant.

Nonetheless, there are development patterns you can use to achieve the effect, such as creating a value object to hold the desired data, the data itself being in private properties with only "getter" methods. Example:

class Credentials {
   public function __construct($credentials) {
       $this->credentials = $credentials;
   }
   public function getCredentials() {
       return $this->credentials;
   }
   private $credentials;
}

Another way:

function credentials($initial = null) {
    static $credentials = null;
    if (null === $credentials) {
        if (empty($initial)) {
            throw new \LogicException('Need to initialize credentials');
        } else {
            $credentials = $initial;
        }
    }
    return $credentials;
}
echo credentials('first time'); // sets and returns value
echo credentials(); // always returns initial set value
echo credentials('second time'); // still echoes initial value

This is not very testable, but it achieves the goal of "settable only once, never modifiable thereafter".

Upvotes: 1

Related Questions