Reputation: 23
I'm trying to get an item from the database and pass it to a new item to push to the database.
$post = $entityManager->getRepository('App:Post')
->find($id);
$comment->setPost($post)
the setPost
looks like the following:
public function setPost(Post $post): self
{
$this->post = $post;
return $this;
}
and the $post
variable:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Post", inversedBy="comments")
* @ORM\JoinColumn(nullable=false)
*/
private $post;
But when i try to set the post like setPost($post)
it gives me the following error:
Expected parameter of type '\App\Entity\Post', 'object' provided
Upvotes: 1
Views: 1318
Reputation: 8374
I assume, that the error you see is from your integrated developent environment (IDE), for example eclipse, vs code, phpstorm, and others. But the code - when actually executed - should work.
Now, the error most likely stems from a static code analysis running in the background of said IDE, which will look at the statement and trying to analyze according to the called methods, accessed properties etc. of which type your variables are.
So, let's do this slowly (and you can probably hover over the $vars
and ->methods()
do verify. The line I'm interested in is
$post = $entityManager->getRepository('App:Post')
->find($id);
so $entityManager
is of type EntityManagerInterface
, which has a getRepository
method with one required parameter of type string
('App:Post'
in your case), and it will return an object of type ObjectRepository
, which has a method find
which requires one parameter (mixed
, don't ask), and returns ?object
which means, an object
or null
. So, $post
is of type object
(best case, or null, in which case it would fail!). Now, the next line obviously expects a parameter of type Post
and not of type object
, thus the warning/notice/error.
Now, static code analysis is quite helpful up to a certain level, but it isn't infallible because it has limitations. It doesn't know what runtime will actually return, it just assumes that the type hints found in the code (of doctrine) are sufficiently specific - which they aren't in your case.
add a doc string to tell static code analysis what the variable $post
's type actually is:
/** @var Post $post */
$post = $entityManager->getRepository('App:Post')
->find($id);
this explicitly tells the static analysis tool, that $post
is of type Post
, maybe you have to write App\Entity\Post
or even \App\Entity\Post
.
Alternatively, you could implement your own PostRepository
(doctrine provides some help) and define a function like function findById($id) :Post
- which would explicitly tell static code analysis, what the return type is when you call it in your code (injected in your function via dependency injection: PostRepostory $postRepository
):
$post = $postRepository->findById($id);
If you're using lots and lots of different entities, this is a very verbose solution but depending on your project it might be worth it, since you explicitly name the dependencies instead of injecting the very unspecific (as we have seen) EntityManagerInterface
. Using the EntityManagerInterface might make testing HELL (imho!).
Upvotes: 3