"Cannot use temporary expression in write context" when assigning to prop on class instance defined as constant

huangapple go评论50阅读模式
英文:

"Cannot use temporary expression in write context" when assigning to prop on class instance defined as constant

问题

以下是您要的内容的翻译部分:

以下代码片段将在PHP 8.2上产生错误:

```php
<?php

const foo = new stdClass();

foo->bar = 'baz';

echo foo->bar;

?>

我期望不会发生错误,因为我正在为属性赋值,而不是尝试重新分配常量。

如果我创建一个新类,扩展stdClass,并添加以下方法:

class extendsStdClass extends stdClass {
    public function set(string $name, mixed $value) {
      $this->$name = $value;
    }
}

然后我可以使用以下语法为属性赋值:

<?php

const foo = new extendsStdClass();

foo->set('bar', 'baz');

echo foo->bar;

?>

但是,代码检查器将不会识别以这种方式设置的属性,也不会提供任何类型提示:

Undefined property: extendsStdClass::$bar

有没有某种原因,我们不能在定义为常量的类实例上写入属性?

英文:

The following code snippet will produce an error on PHP 8.2:

<?php

const foo = new stdClass();

foo->bar = 'baz';

echo foo->bar;

?>

I would expect that an error would not occur, since I am assigning to the prop rather than trying to reassign the constant.

If I create a new class, extending stdClass, and add the following method:

class extendsStdClass extends stdClass {
    public function set(string $name, mixed $value) {
      $this->$name = $value;
    }
}

then I can assign to props using the following syntax:

<?php

const foo = new extendsStdClass();

foo->set('bar', 'baz');

echo foo->bar;

?>

but, the linter will not recognize props being set in this way, nor provide any type hinting:

Undefined property: extendsStdClass::$bar

Is there some reason we are not able to write to props on a class instance that is defined as a constant?

答案1

得分: 0

Sure, here's the translated code:

我想要能够在一个命名空间中定义这个常量,并访问/修改它。

如果您想要修改它,*那它就不是一个常量*

如果您 *真的* 想要一个常量,那么您可以使用数组来获取键/值对:

namespace MyNamespace {
    const FOO = [
        'one' => 1,
        'two' => 2,
    ];
}

然后在任何地方引用它:

print_r(\MyNamespace\FOO);

得到:

Array
(
    [one] => 1
    [two] => 2
)

您可以使用数组标记提取单个值:

echo \MyNamespace\FOO['one'];

如果您想要一个可以直接通过命名空间引用并且仍然可以修改的东西,您可以创建一个带有静态存储的类。有点像半吊子的单例:

namespace MyNamespace;

class Foo
{
    private static array $data = [];
    public static function get($name)
    {
        return self::$data[$name] ?? null;
    }
    public static function set($name, $value)
    {
        self::$data[$name] = $value;
    }
}

然后您可以从任何地方设置值:

\MyNamespace\Foo::set('one', 1);

并且从任何地方获取值:

echo \MyNamespace\Foo::get('one');
英文:

> I'd like to be able to define this const in a namespace, and access/modify it via

If you want to modify it, then it's not a const.

If you actually want a const, then you can just use an array to get key/value pairs:

namespace MyNamespace {
    const FOO = [
        'one' => 1,
        'two' => 2,
    ];
}

Then reference it anywhere via:

print_r(\MyNamespace\FOO);

Yields:

Array
(
    [one] => 1
    [two] => 2
)

And you can pull out a single value with array notation:

echo \MyNamespace\FOO['one'];

If you want something that you can reference directly by namespace, and still modify, you could create a class with static storage. Sort of like a half-assed singleton:

namespace MyNamespace;

class Foo
{
    private static array $data = [];
    public static function get($name)
    {
        return self::$data[$name] ?? null;
    }
    public static function set($name, $value)
    {
        self::$data[$name] = $value;
    }
}

Then you can set values from anywhere:

\MyNamespace\Foo::set('one', 1);

And get values from anywhere:

echo \MyNamespace\Foo::get('one');

huangapple
  • 本文由 发表于 2023年2月6日 02:40:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75354638.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定