Doctrine PHPStan entity relation Collection 从未写过,只读过

Doctrine PHPStan entity relation Collection never written, only read

我正在尝试根据 Doctrine 和 PHPStan 使用正确的类型,但是对于实体关系,我似乎无法做到正确。

我正在使用 PHP 8.1.6、Doctrine 2.6.3、PHPStan 1.7.3 和 PHPStan/Doctrine 1.3.6。

我的实体如下所示:

#[ORM\Entity]
class Thing
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(options: ['unsigned' => true])]
    private ?int $id;

    #[ORM\Column]
    private string $name;

    /** @var Collection&iterable<Item> $items */
    #[ORM\OneToMany(mappedBy: 'thing', targetEntity: Item::class)]
    private Collection $items;

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return iterable<Items>
     */
    public function getItems(): iterable
    {
        return $this->items;
    }
}

对于 ID,它没有抱怨(条令规则加载到 PHPStan 中,工作正常)。但是,对于 $items 集合,它表示“从未写入,仅读取”。这是没有意义的,因为它是一个集合,不会被写入(而是通过它的方法添加)。

我不太明白为什么它会给我这个错误,而且我似乎找不到太多关于它的信息,除了“它应该工作”。

对于那个私人 属性,您没有“setter”或“adders/removers”。所以,PhpStan 确实是对的。

要么完全从该关系的反面删除 属性(又名 Thing class),要么添加一些“adders/removers”。

这通常看起来像这样。

public function addItem(Item $item): self
{
    if (!$this->items->contains($items)) {
        $this->items[] = $item;
        // optional but keeps both sides in sync
        $item->setThing($this);
    }

    return $this;
}

public function removeItem(Item $item): self
{
    $this->items->removeElement($item);
    // should your Item::thing be not nullable, skip this
    $item->setThing(null);

    return $this;
}