【问题标题】:Entity expected object returned symfony实体期望对象返回 symfony
【发布时间】:2020-04-18 15:11:40
【问题描述】:

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

$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' 提供

【问题讨论】:

  • 'App:Post' 看起来有点不对劲,你试过Post::class(使用适当的use 子句)吗?
  • 同样的问题,我试过App:Post,因为我是在网上找到的。当我转储 `$post` 时,输出是正确的。我从中得到了所有正确的数据。
  • App:Post 和 Post::class 就检索存储库而言是相同的。 Doctrine 只有一个处理 App:Post 的命名空间系统。 Post::class 可能是更好的选择,因为您的 IDE 会提供更多帮助。就问题而言,既然您确认 $post 是预期的类,那么可能正在执行其他一些代码?也许暂时从 setPost 中删除 typehint 看看会发生什么。
  • @Cerad 当我从SetPost 中删除Post 时它可以工作,所以现在它是SetPost($post)。但我不知道为什么它有效,以及它是否是好的做法。
  • 这不是一个好习惯。您的 Post 实体和 Comment 实体是否在同一个命名空间中,即 App\Entity\Comment?我想您也可以尝试神奇地清除缓存。 php版本?如果可能,请尝试转到 7.4.4。

标签: symfony object doctrine relation many-to-one


【解决方案1】:

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

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

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

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

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

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

轻松解决

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

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

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

硬修复

或者,您可以实现自己的PostRepository(doctrine 提供一些帮助)并定义一个类似function findById($id) :Post 的函数 - 它会明确告诉静态代码分析,当你在你的代码中调用它(通过依赖注入在你的函数中注入:PostRepostory $postRepository):

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

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

【讨论】:

  • 感谢您的精彩解释!我现在了解这个问题以及如何解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
  • 2018-08-12
  • 2014-06-01
相关资源
最近更新 更多