Set id in constructor, or generate it when asked for?
I would go with lazy loading. Generate the id when requested
private $id;

public function getId()
{
    if ($this-&gt;id === null) {
        $this-&gt;id = //your logic to generate the id here
    }
    return $this-&gt;id;
}

and don't use anywhere else $this-&gt;id even inside the class. Use $this-&gt;getId() everywhere.
using $this-&gt;getId() everywhere will ensure that you always get the generated id (the same one everytime) and you are sure you don't get the null initial value.