PHP:类中的静态只读属性

问题描述 投票:0回答:5

我的问题是:我需要重载类中静态变量的标准 get 和 set...但是 php 中没有提供这样的功能...它在 2008 年被要求但仍未实现...只读也是如此...

我的问题:有没有一种方法可以使静态属性可以从外部读取,但又不能被修改?

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

我不能使用const,因为有些变量包含数组。

也许有一些解决方法?

是的,我知道我可以像 aaa::Get('qwe') 一样,但这不好......

php static get set magic-methods
5个回答
5
投票

直接回答您的问题:不,您不能将常规属性标记为只读。如果你想设置基本类型(除了

array
),它永远不会改变,你应该使用常量

const QWE = '666';

这不适用于对象和数组。我看到两个(可以说)“解决方案”

  1. 使用吸气剂

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

    我不太喜欢它们(“属性定义状态,而不是行为,就像方法一样”)。您总是获得两倍于属性的附加方法,如果您有很多属性,这将极大地破坏您的类。然而,据我所知,这是实现您想要实现的目标的唯一方法。

  2. 相信您的用户;)评论您的属性并说类似“如果您更改此值,可能会出现某些问题,并且这是您自己的错”。

    /**
     * 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';
    

    不太好,但至少你可以说“我告诉过你了”。


2
投票

PHP 8.1 中引入了只读属性,但不支持静态只读属性。

来自RFC

不支持只读静态属性。这是一个技术限制,因为不可能非侵入地实现只读静态属性。结合只读静态属性的可疑用途,目前认为这不值得。

但是,您可以声明一个静态函数来或多或少地获得相同的最终结果。

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

1
投票

如果该值永远不会改变,您可以使用

const
代替。 否则,无法满足您的限制(除了通过扩展在 PHP 中挂钩函数调用之外,但即使如此,您也需要将静态变量访问更改为函数调用;否则,您必须修补 PHP)。

当然,你的应用程序所做的是否是良好的设计是非常值得怀疑的。依赖于改变静态属性或多或少与依赖于全局变量相同。


1
投票

这更容易一点:

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

它不允许更改,并且仍然易于访问:

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

我知道这并不理想,但你可以全部更换

aaa::$qwe 

aaa::qwe()

0
投票

如果 php 提供了

getStatic()
方法,那就太好了,但由于它没有,你可以重新调整
__callStatic()
的用途来获取它们,如下所示:

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

只需将变量名作为函数调用即可。它是可扩展的,因为您不需要创建任何特殊的 getter 函数即可工作。

© www.soinside.com 2019 - 2024. All rights reserved.