13

My problem is: I need to overload standard get and set for static variables in class... but no such functionality provided in php... it was asked in 2008 and still not implemented... Same goes for readonly...

My question: is there a way to make a static property accesible for reading from outside, but protected from modification?

echo aaa::$qwe; //<--- echoes value of $qwe
aaa::$qwe = '666'; //<--- throws an error because variable is protected from modification

I can't use const because some variables contain arrays.

Maybe there are some workarounds?

Yeah, I know I can make it like aaa::Get('qwe') but that's no good...

3
  • Because I would need to change 2mb of existing code base, and also it's not clean, plus there are other reasons not dependent on me :) Commented Dec 7, 2011 at 9:53
  • 1
    Why not use a class constant? Or will the variable be modified internally? Commented Dec 7, 2011 at 9:56
  • Some variables store arrays and other data not allowed for const... otherwise yes, it would be the best solution. Commented Dec 7, 2011 at 9:58

5 Answers 5

5

Directly answering your question: No, you cannot mark regular properties as readonly. If you want to set primitive types (except array), that will never change, you should use constants

const QWE = '666';

That doesn't work for objects and arrays. I see two (lets say) "solutions"

  1. Use Getter

    private $qwe;
    public function getQwe() { return $this->qwe; }
    protected function setQwe($value) { $this->qwe = $value; }
    

    I don't like them very much ("Properties define the state, not the behavior, like methods do"). You always get twice as much additional methods as properties and if you have many properties, this will extremely blow up your class. However, it's as far as I can see the only way to implement what you want to achieve.

  2. Trust your users ;) Comment your property and say something like "If you change this value, probably something will break and its your very own fault".

    /**
     * QWE
     *
     * This property should be treatened as "readonly". If you change this value
     * something scary will happen to you.
     *
     * @readonly
     * @var string
     */
    public $qwe = '666';
    

    Its not great, but at least you can say "I told you".

Sign up to request clarification or add additional context in comments.

5 Comments

Only option 2 would be possible :) But leaving very important variables like that is no good :)
Trust your users...(Keep reading)!?!(wait a minute dahell I just read??!)...(Facepalm).That sir is the funiest thing I've read all day!!
@Sebastien I don't know... whats the funny part? You know, that with "users" I mean other developers and not visitors of the application? And you know, that if they are "not trustworthy" they shot themself in their own foot. Nothing you have to take care about ;)
@KingCrunch NEVER TRUST ANY USER might it be the app visitor or the people that develop with your classes, There is a reason why encapsulation, Design by contract (DbC) and validation are commonly use.
@Sebastien Again. This "user" is a developer, that simply use your code own their own responsibility. I am aware of design specifications, but I am also aware of the fact, that part of the contract is the documentation.
3

Readonly properties were introduced in PHP 8.1, but static readonly properties are not supported.

From the RFC:

Readonly static properties are not supported. This is a technical limitation, in that it is not possible to implement readonly static properties non-intrusively. In conjunction with the questionable usefulness of readonly static properties, this is not considered worthwhile at this time.

However you can declare a static function to more or less get the same end result.

public static function getType(): string
{
    return 'Duck';
}

1 Comment

And if the value does not need to be dynamic, a class constant can do the same job.
1

If the value never changes, you can use const instead. 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. Relying on changing static properties is more or less the same as relying on global variables.

3 Comments

Well, that's what I have to live with :) Existing codebase... And unfortunately I can't use const because some variables store arrays...
If the design allows such a change, you can save the arrays as CSV, or maybe JSON-encoded: const $qwe = '["666"]'
Hm, that is actually interesting idea!
1

This is a bit easier:

class aaa{
private static $qwe='rty';
public static function qwe() { return self::$qwe; }
}

It does not allow changes, and is still easy to access:

aaa::$qwe = 'something'; // fails
echo aaa::qwe(); // success

I know it is not ideal, but you can do a replace all

aaa::$qwe 

with

aaa::qwe()

1 Comment

Thanks Leri, fixed the first code snippet from $this->qwe; to self::$qwe. please re-rate my answer if you feel it is any better.
0

It would be nice if php offered a getStatic() method but since it doesn't you can repurpose __callStatic() to fetch them like this:

class Foo
{
    private static $readonly_var = 'FOO';
    public static function __callStatic($name, $args) {
        return self::${$name};
    }
}
echo Foo::readonly_var() . PHP_EOL;

Simply call the variable name as a function. It's scalable since you don't need to create any special getter function for it to work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.