是否可以将 ParamConverter 与不同的类一起使用,具体取决于被调用的路由?
我们假设我有一个父类Food
,有两个孩子Fruit
班级和Vegetable
班级。
我希望能够做到这样的事情:
/**
*
* @Route("fruit/{id}", name="fruit_show")
* @ParamConverter("food", class="AppBundle:Fruit")
* @Route("vegetable/{id}", name="vegetable_show")
* @ParamConverter("food", class="AppBundle:Vegetable")
*/
public function showAction(Food $food)
{ ... }
答案 0 :(得分:4)
似乎无法完全按照自己的意愿行事。但是有可能通过两个简单的包装器动作来获得所需的东西。您甚至不需要明确的@ParamConverter
注释。 E.g。
/**
*
* @Route("fruit/{id}", name="fruit_show")
*/
public function showFruitAction(Fruit $fruit)
{
return $this->showAction($fruit)
}
/**
*
* @Route("vegetable/{id}", name="vegetable_show")
*/
public function showVegetableAction(Food $food)
{
return $this->showAction($vegetable)
}
public function showAction (Food $food)
{ ... }
答案 1 :(得分:2)
我在这里发现的问题是ParamConverter使用注释中的最后一项。如果它与fruit_show
路由匹配,则$ food变量是AppBundle:Vegetable类的实例。如果它与vegetable_show
路线匹配,则相同。
class FoodController
{
/**
* @Route("/items/fruits/{id}", methods={"GET"}, name="fruits_show")
* @ParamConverter("food", class="AppBundle:Fruit")
* @Route("/items/vegetables/{id}", methods={"GET"}, name="vegetables_show")
* @ParamConverter("food", class="AppBundle:Vegetable")
*/
public function foodAction(Request $request, $food)
{
//
}
}
您可以使用的一种解决方法是编写自己的ParamConverter:
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
use Symfony\Component\HttpFoundation\Request;
class FoodConverter implements ParamConverterInterface
{
protected $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function apply(Request $request, ParamConverter $configuration)
{
$id = $request->get('id');
$route = $request->get('_route');
$class = $configuration->getOptions()[$route];
$request->attributes->set($configuration->getName(), $this->entityManager->getRepository($class)->findOneById($id));
return true;
}
public function supports(ParamConverter $configuration)
{
return $configuration->getName() === 'food';
}
}
将其添加到您的服务中:
services:
food_converter:
class: App\SupportClasses\FoodConverter
arguments: ['@doctrine.orm.entity_manager']
tags:
- {name: request.param_converter, priority: -2, converter: food_converter}
像这样使用它:
class FoodController
{
/**
* @Route("/items/fruits/{id}", methods={"GET"}, name="fruits_show")
* @Route("/items/vegetables/{id}", methods={"GET"}, name="vegetables_show")
* @ParamConverter("food", converter = "food_converter" class="App:Food", options={"fruits_show" = "App:Fruit", "vegetables_show" = "App:Vegetable"})
*/
public function foodAction(Request $request, $food)
{
var_dump($food);
exit();
}
}