具有许多属性的不可变对象

I've got a class that I want to make immutable but that class has a lot of properties.

<?php

class Gameworld {

    /** @var string */
    private $name;

    /** @var string */
    private $type;

    /** @var bool */
    private $is_online;

    /** @var int */
    private $online_players;

    /** @var int */
    private $online_players_record;

    /** @var string */
    private $description;

    /** @var string */
    private $location;

    /** @var \DateTime */
    private $created_at;

}

How to create such object? When I introduce public function __construct() with all those properties it will get bloated. If I introduce setters it won't be immutable anymore.


EDIT: I was thinking about making setters but ones that could be only used once. Thanks to that I won't have bloated constructor but for some reason it seems not like a good idea. Something like:

class Gameworld {

    ... old properties ...

    /** @var array */
    private $used_setters = [];

    public function setName(string $name){
        if(in_array('name', $this->used_setters)){
            throw new ImmutableException('Class Gameworld is immutable.');
        }

        $this->name = $name;
        $this->used_setters[] = 'name';
    }

}

I would use __set() magic method to check if the value is set else I would throw an exception:

class Gameworld {

    /** @var string */
    private $name;

    /** @var string */
    private $type;

    /** @var bool */
    private $is_online;

    /** @var int */
    private $online_players;

    /** @var int */
    private $online_players_record;

    /** @var string */
    private $description;

    /** @var string */
    private $location;

    /** @var \DateTime */
    private $created_at;

    public function __set($property, $value)  
    {  
        if (property_exists($this, $property)) {  
            if(is_null($this->$property)){
                $this->$property = $value;
                return $this;
            }
            throw MyCustomException();
        }
        throw UndefinedClassVariableException();
    }
}

A basic usage would be:

$x = new Gameworld();
$x->name = "OK";
$x->is_online = true;
$x->name="Exception";

P.S: Exceptions must extend the base exception class or you could trigger or log an error, depends on what you want

P.S.S: An alternative sollution would be to use __call() method and check if the value is null

I would suggest passing properties as an array argument like

__construct( array $properties )
{
  $this->property = $properties['property'];
  ....
}