首页 > 解决方案 > 实体期望对象返回 symfony

问题描述

我正在尝试从数据库中获取一个项目并将其传递给一个新项目以推送到数据库。

$post = $entityManager->getRepository('App:Post')
            ->find($id);

$comment->setPost($post)

如下setPost所示:

public function setPost(Post $post): self
    {
        $this->post = $post;

        return $this;
    }

$post变量:

 /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Post", inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $post;

但是,当我尝试像setPost($post)这样设置帖子时,会出现以下错误:

'\App\Entity\Post'、'object' 类型的预期参数提供

标签: symfonyobjectdoctrinerelationmany-to-one

解决方案


我假设您看到的错误来自您的集成开发环境 (IDE),例如 eclipse、vs code、phpstorm 等。但是代码 - 当实际执行时 - 应该可以工作。

现在,错误很可能源于在所述 IDE 后台运行的静态代码分析,它会查看语句并尝试根据调用的方法、访问的属性等进行分析。变量的类型。

所以,让我们慢慢来(你可以将鼠标悬停在 上$vars->methods()进行验证。我感兴趣的行是

$post = $entityManager->getRepository('App:Post')
            ->find($id);

so$entityManager是 type EntityManagerInterface,它有一个getRepository方法需要一个类型的参数string'App:Post'在你的情况下),它会返回一个 type 的对象ObjectRepository,它有一个find需要一个参数的方法(mixed不要问),并返回?object这意味着,objectnull. 所以,$post是类型object(最好的情况,或者为空,在这种情况下它会失败!)。现在,下一行显然需要一个 type 参数Post而不是 type参数object,因此是警告/通知/错误。

现在,静态代码分析在一定程度上很有帮助,但它并非万无一失,因为它有局限性。它不知道运行时实际上会返回什么,它只是假设在代码(教义)中找到的类型提示足够具体——在你的情况下它们不是。

简单的修复

添加一个文档字符串来告诉静态代码分析变量$post的类型实际上是什么:

/** @var Post $post */
$post = $entityManager->getRepository('App:Post')
            ->find($id);

这明确地告诉静态分析工具,即$post类型Post,也许你必须写App\Entity\Post甚至\App\Entity\Post

硬修复

或者,您可以实现自己的PostRepository(教义提供了一些帮助)并定义一个函数,例如function findById($id) :Post- 它会明确告诉静态代码分析,当您在代码中调用它时返回类型是什么(通过依赖注入注入到您的函数中:)PostRepostory $postRepository

$post = $postRepository->findById($id);

如果您使用大量不同的实体,这是一个非常冗长的解决方案,但取决于您的项目,这可能是值得的,因为您明确命名依赖项而不是注入非常不具体的(如我们所见)EntityManagerInterface。使用 EntityManagerInterface 可能会使测试地狱(恕我直言!)。


推荐阅读