I would like to start using Criteria
, but I have a pretty basic problem, I couldn't find any information about.
Let's say I have an entity that have a method getStudents
. This method can return either ArrayCollection
or PersistentCollection
, both have the matching
method coming from the Selectable
interface. The question is, what should I type hint as a return value of the getStudents
method? Everywhere where I looked, people suggest to use the Collection
interface as a type hint, which is shared by both these classes, but this interface doesn't extend Selectable
so it doesn't have matching
method! So it looks like there is some inconsistency.
In many tutorials, for example here, we have something like this:
public function getExpertScientists()
{
$criteria = Criteria::create()
->andWhere(Criteria::expr()->gt('yearsStudied', 20))
->orderBy(['yearsStudied', 'DESC']);
return $this->getGenusScientists()->matching($criteria);
}
But if $this->getGenusScientists()
is type hinting Collection
that doesn't have the matching method, it will generate a warning in my IDE, and it feels like something is wrong.
How do you deal with this? Do we have any options other than ignoring IDE warnings or typehinting everything that can be returned by our getter (like: @return ArrayCollection|PersistentCollection
)?
Not sure about other IDEs, so I'll be answering for PHPStorm.
I was always using @return Collection|Selectable
and it works great.
And if the method is returning e.g. Student
entities, you can also typehint it as.
@return Collection|Selectable|Student[]
so the IDE understands both Doctrine Collections things, but it can also typehint Student
methods if you iterate over it later or access individual elements.
Of course it semantically does not make much sense, because you'd expect something like @return Collection&Selectable&Student[]
since you are returning Intersection Type and not Union Type.
And from PHPStorm version 2018.3, you can actually use even the Intersection Type (see this update), so @return Collection&Selectable&Student[]
works, which helps you distinguish between the actual Union and Intersection Type in your code.