I am attempting to use the correct typings according to Doctrine and PHPStan, however with an entity relation, I can't seem to make it right.
I am using PHP 8.1.6, Doctrine 2.6.3, PHPStan 1.7.3 and PHPStan/Doctrine 1.3.6.
My entity looks like this:
#[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;
}
}
For the ID, it's not complaining (doctrine rules are loaded into PHPStan, which works just fine). However, for the $items
Collection, it's saying "is never written, only read". This makes no sense as it is a Collection, and will not be written (but rather added to through it's methods).
I am not quite understanding why it is giving me this error, and I can't seem to find much about it, other than "It should work".
CodePudding user response:
You have no "setters" nor "adders/removers" for that private property. So, PhpStan is indeed right.
Either remove that property entirely from the inversed side of that relation (aka in the Thing
class) or add some "adders/removers".
This usually looks something like this.
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;
}