Immutable objects in PHP?

后端 未结 6 1258
暗喜
暗喜 2020-12-31 06:34

Is it a good idea to create objects that cannot be changed in PHP?

For example a date object which has setter methods, but they will always return a new instance of

6条回答
  •  轮回少年
    2020-12-31 07:22

    I made a little trait avoiding using Reflection to ease the implementation of immutability: https://github.com/jclaveau/php-immutable-trait

    Obviously, as it's not a language feature, it won't impeach mutation by magic but lighten the code of the mutators that must clone the current instance before being applied. Applied to Massimiliano's example it would produce

    class ImmutableValueObject
    {
        use JClaveau\Traits\Immutable;
    
        private $val1;
        private $val2;
    
        public function __construct($val1, $val2)
        {
            $this->val1 = $val1;
            $this->val2 = $val2;
        }
    
        public function getVal1()
        {
            return $this->val1;
        }
    
        public function withVal1($val1)
        {
            // Just add these lines at the really beginning of methods supporting
            // immutability ("setters" mostly)
            if ($this->callOnCloneIfImmutable($result))
                return $result;
    
            // Write your method's body as if you weren't in an Immutable class
            $this->val1 = $val1;
            return $this;
        }
    
        public function getVal2()
        {
            return $this->val2;
        }
    
        public function withVal2($val2)
        {
            if ($this->callOnCloneIfImmutable($result))
                return $result;
    
            $this->val2 = $val2;
    
            return $this;
        }
    }
    
    • You can see that you don't return $copy here but $this as Kanstantsin K noticed.
    • In native PHP https://secure.php.net/manual/en/class.datetimeimmutable.php has mutators that will return new instances with modification applied. So copy pasting sentences saying that immutable objects shouldn't have mutators doesn't seem super interesting.
    • The practice of using "withXXX" instead of "setXXX" is super interesting, thanks for the suggestion! I personnaly used "becomesXXX" for the api chainging the mutability of the instance (optionnal API in the trait SwitchableMutability).

    Hoping it can help some people here!

    PS: Suggestions on this little feature are really welcome :) : https://github.com/jclaveau/php-immutable-trait/issues

提交回复
热议问题