PHP:不可变的公共成员字段

发布于 2024-12-03 12:17:44 字数 146 浏览 0 评论 0原文

我需要创建一个不可变的类,它只是一个成员字段容器。我希望其字段在其构造函数中实例化一次(值应作为构造函数的参数给出)。我希望这些字段是公开的但不可变的。我可以使用 Java 在每个字段之前使用 final 关键字来完成此操作。 PHP 中是如何完成的?

I need to create an immutable class which is simply a member field container. I want its fields to be instantiated once in its constructor (the values should be given as parameters to the constructor). I want the fields to be public but immutable. I could have done it with Java using the final keyword before each field. How is it done in PHP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一曲琵琶半遮面シ 2024-12-10 12:17:44

您应该使用 __set__get 魔术方法,并将该属性声明为受保护或私有:

/**
 * @property-read string $value
 */
class Example
{
    private $value;

    public function __construct()
    {
        $this->value = "test";
    }

    public function __get($key)
    {
        if (property_exists($this, $key)) {
            return $this->{$key};
        } else {
            return null; // or throw an exception
        }
    }

    public function __set($key, $value)
    {
        return; // or throw an exception
    }
}

示例:

$example = new Example();
var_dump($example->value);
$example->value = "invalid";
var_dump($example->value);

输出:

string(4) "test"
string(4) "test"

@property-read 应该可以帮助您的 IDE 确认此神奇属性的存在。

You should use __set and __get magic methods and declare that property as protected or private:

/**
 * @property-read string $value
 */
class Example
{
    private $value;

    public function __construct()
    {
        $this->value = "test";
    }

    public function __get($key)
    {
        if (property_exists($this, $key)) {
            return $this->{$key};
        } else {
            return null; // or throw an exception
        }
    }

    public function __set($key, $value)
    {
        return; // or throw an exception
    }
}

Example:

$example = new Example();
var_dump($example->value);
$example->value = "invalid";
var_dump($example->value);

Outputs:

string(4) "test"
string(4) "test"

@property-read should help your IDE acknowledge existence of this magic property.

莫多说 2024-12-10 12:17:44

您可以使用 __set() 魔术方法,并在有人尝试直接设置属性时引发异常。

class ClassName {
    public function __set($key, $value) {
        throw new Exception('Can't modify property directly.');
    }
}

但是,这将阻止对属性的修改,无论它们是否是公共的。

You could use the __set() magic method and throw an exception when someone tries to set a property directly.

class ClassName {
    public function __set($key, $value) {
        throw new Exception('Can't modify property directly.');
    }
}

However, this would prevent modification of properties regardless of whether they're public or not.

溺深海 2024-12-10 12:17:44

神奇方法

可以做得更好 - 如果您有 dinamyc 字段数

   class ClassName {
        private $fields = array(); 
        // use class : $cl = new ClassName(array('f'=>2,'field_4'=>5,''12));
        // echo $cl->field_4; echo $cl->f;
        public function __construct($data= array()) 
        {
           if (!is_array($data) || !count($data)) throw new Exception('Not enough args')
           foreach ($data as $key=>$val)
           {
              if (is_numeric($key))
                $this->fields['field_'.$key] = $val;
              else
                $this->fields[$key] = $val;
           }     
        }
          /* in this case you can use this class like $cl = new ClassName(12,14,13,15,12); echo $cl->field_1;
      public function __construct() 
    {
           $ata = funcs_get_args();
      
           if (!count($data)) throw new Exception('Not enough args')
           foreach ($data as $key=>$val)
           {
              if (is_numeric($key))
                $this->fields['field_'.$key] = $val;
              else
                $this->fields[$key] = $val;
           }     
    }
    */
        public function __get($var) {
            if (isset($this->fields[$var]))
                return $this->fields[$var];
            return false; 
            //or throw new Exception ('Undeclared property');
        }
    }

magic methods

so you can do better - if you have a dinamyc count of fields

   class ClassName {
        private $fields = array(); 
        // use class : $cl = new ClassName(array('f'=>2,'field_4'=>5,''12));
        // echo $cl->field_4; echo $cl->f;
        public function __construct($data= array()) 
        {
           if (!is_array($data) || !count($data)) throw new Exception('Not enough args')
           foreach ($data as $key=>$val)
           {
              if (is_numeric($key))
                $this->fields['field_'.$key] = $val;
              else
                $this->fields[$key] = $val;
           }     
        }
          /* in this case you can use this class like $cl = new ClassName(12,14,13,15,12); echo $cl->field_1;
      public function __construct() 
    {
           $ata = funcs_get_args();
      
           if (!count($data)) throw new Exception('Not enough args')
           foreach ($data as $key=>$val)
           {
              if (is_numeric($key))
                $this->fields['field_'.$key] = $val;
              else
                $this->fields[$key] = $val;
           }     
    }
    */
        public function __get($var) {
            if (isset($this->fields[$var]))
                return $this->fields[$var];
            return false; 
            //or throw new Exception ('Undeclared property');
        }
    }
梦在深巷 2024-12-10 12:17:44
<?php 

declare(strict_types=1);

final class Immutable 
{
    /** @var string */
    private $value;

    public static function withValue(string $value): self
    {
        return new self($value);
    }

    public function __construct(string $value) 
    {
        $this->value = $value;
    }

    public function value(): string 
    { 
        return $this->value;
    }
}

// Example of usage:

$immutable = Immutable::withValue("my value");
$immutable->value(); // You can get its value but there is no way to modify it.
<?php 

declare(strict_types=1);

final class Immutable 
{
    /** @var string */
    private $value;

    public static function withValue(string $value): self
    {
        return new self($value);
    }

    public function __construct(string $value) 
    {
        $this->value = $value;
    }

    public function value(): string 
    { 
        return $this->value;
    }
}

// Example of usage:

$immutable = Immutable::withValue("my value");
$immutable->value(); // You can get its value but there is no way to modify it.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文