无法从请求信息中猜测如何获取Doctrine实例

问题描述 投票:0回答:6

我收到了“500 内部服务器错误 - LogicException:无法猜测如何从请求信息中获取 Doctrine 实例”。

这是我的控制器的动作定义:

/**
 * @Route("/gatherplayer/{player_name}/{gather_id}")
 * @Template()
 */
public function createAction(Player $player, Gather $gather)
{
  // ...
}

它不起作用,可能是因为 Doctrine 2 无法“猜测”...那么我该如何让 Doctrine 2 猜测呢?

php symfony doctrine-orm
6个回答
38
投票

Doctrine 不知道如何使用请求参数来查询函数签名中指定的实体。

您需要通过指定一些映射信息来帮助它:

/**
  * @Route("/gatherplayer/{player_name}/{gather_id}")
  *
  * @ParamConverter("player", options={"mapping": {"player_name" : "name"}})
  * @ParamConverter("gather", options={"mapping": {"gather_id"   : "id"}})
  *
  * @Template()
  */
public function createAction(Player $player, Gather $gather)
{
  // ...
}

12
投票
/**
 * @Route("/gatherplayer/{name}/{id}")
 * @Template()
 */
public function createAction(Player $player, Gather $gather)

我在 paramconverter 的(差?)文档中没有找到任何帮助,因为它没有描述它是如何工作的,它如何猜测多个参数和东西。另外,我不确定是否需要它,因为我刚刚写的内容可以正常工作。

我的赌注是不使用我的属性名称,因此学说无法猜测正确。我将 {player_name} 更改为 {name},将 {gather_id} 更改为 {id}。

然后我将其实体中的 id 名称从“id”更改为“id_gather”和“id_player”,这样我现在就可以做到这一点了:

/**
 * @Route("/gatherplayer/{id_player}/{id_gather}")
 * @Template()
 */
public function createAction(Player $player, Gather $gather)

这比

有效得多
 * @Route("/gatherplayer/{id}/{id}")

现在我想知道如何才能完成这项工作

 /**
  * @Route("/gatherplayer/{player}/{gather}")
  * @Template()
  */
 public function deleteAction(Gather_Player $gather_player)

5
投票

试试这个:

/**
 * @Route("/gatherplayer/{player_name}/{gather_id}")
 * @ParamConverter("player", class="YourBundle:Player")
 * @ParamConverter("gather", class="YourBundle:Gather")
 * @Template()
 */
public function createAction(Player $player, Gather $gather)

2
投票

@Route注解签名上的参数必须与实体字段匹配,以便Doctrine自动进行转换。

否则,您需要使用注释 @ParamConverter 手动进行转换,正如其他响应中提到的那样。


0
投票

@1ed 是对的,您应该定义一个 @paramConverter 才能获取 Player 实例或 Gather 实例。


0
投票

从 symfony 6.2 开始,SensioFrameworkExtraBundle 已弃用。注释路由、参数转换等功能现在直接集成在 Symfony 中。

请注意,ParamConverter 现在称为 ValueResolver

您需要使用 Symfony > 6.2、PHP >= 8.1 和 DoctrineBundle >= 2.7.1

现在可以轻松地将 ID 映射到实体:

#[Route('/post/{id}')]
public function show(Post $post): Response
{
    //  $post is a Post entity
}

此行为默认激活,可以通过

doctrine.orm.controller_resolver.auto_mapping
设置为 false 来禁用。

如果您以不同方式获取对象,例如通过另一个属性,您现在可以使用

ParamConverter
php 属性,而不是使用 SensioFrameworkExtraBundle 中的
#[MapEntity]

上面发布的链接中的示例,在使用 slug 查找实体时将 ParamConverter 替换为 MapEntity:

#[ParamConverter('post', options: ['mapping' => ['postSlug' => 'slug']])]
public function addComment(Request $request, Post $post): Response

变成:

use Symfony\Bridge\Doctrine\Attribute\MapEntity;
public function addComment(
    Request $request,
    #[MapEntity(mapping: ['postSlug' => 'slug'])] Post $post
): Response

MapEntity 有很多其他有用的选项

请参阅有关自动获取对象(EntityValueResolver)

的文档
© www.soinside.com 2019 - 2024. All rights reserved.