在我的控制器中,我使用了几个功能。在这个函数中我使用类似的代码。
所以我想知道是否有可能将此代码外包而不必重复编写。如果可以的话,最好的方法是什么?
class PagesController extends AbstractController
{
/**
* @Route("/documents/{slug}", name="documents", methods={"GET","POST"})
*/
public function documents($slug, Request $request)
{
$page = $this->getDoctrine()->getRepository(Pages::class)->findOneBy(['slug'=>$slug]);
$entityManager = $this->getDoctrine()->getManager();
$cmf = $entityManager->getMetadataFactory();
$classes = $cmf->getMetadataFor($relation_name);
$fieldMappings = $classes->fieldMappings;
$associationMappings = $classes->associationMappings;
$fields = (object)array_merge((array)$fieldMappings, (array)$associationMappings);
}
/**
* @Route("/blog/{slug}", name="single", methods={"GET","POST"})
*/
public function blog($slug, Request $request)
{
$page = $this->getDoctrine()->getRepository(Pages::class)->findOneBy(['slug'=>$slug]);
$entityManager = $this->getDoctrine()->getManager();
$cmf = $entityManager->getMetadataFactory();
$classes = $cmf->getMetadataFor($relation_name);
$fieldMappings = $classes->fieldMappings;
$associationMappings = $classes->associationMappings;
$fields = (object)array_merge((array)$fieldMappings, (array)$associationMappings);
}
/**
* @Route("/contact/{slug}", name="contact", methods={"POST", "GET"})
*/
public function contact($slug, Request $request)
{
$page = $this->getDoctrine()->getRepository(Pages::class)->findOneBy(['slug'=>$slug]);
$entityManager = $this->getDoctrine()->getManager();
$cmf = $entityManager->getMetadataFactory();
$classes = $cmf->getMetadataFor($relation_name);
$fieldMappings = $classes->fieldMappings;
$associationMappings = $classes->associationMappings;
$fields = (object)array_merge((array)$fieldMappings, (array)$associationMappings);
}
}
这里的关键字是服务。将业务逻辑移动到其他类,并使用autowiring将其自动注入控制器。这是一个Symfony Best Practice:
Symfony遵循“瘦控制器和胖模型”的理念。这意味着控制器应该只包含协调应用程序不同部分所需的薄层代码。
您应该阅读这些最佳实践!
您可以在控制器类和特定操作中注入服务:
class PagesController extends AbstractController
{
public function __construct(Rot13Transformer $transformer)
{
$this->transformer = $transformer;
}
/**
* @Route("/documents/{slug}", name="documents", methods={"GET","POST"})
*/
public function documents($slug, Request $request, PagesRepository $repo)
{
$page = $repo->findOneBy(['slug'=>$slug]);
$foo = $repo->doSomethingDifferentWithEntities($page)
$bar = $this->transformer->transform($foo);
}
}
您可以使用私有方法并调用它,但在您的情况下,您可以在参数中使用Page
typehint:
/**
* @Route("/contact/{slug}", name="contact", methods={"POST", "GET"})
*/
public function contact(Page $slug, Request $request)
@Jarla除了@Stephan Vierkant回答你可以使用@ParamConverter annotation在你的情况下,它将是:
/**
* @Route("/documents/{slug}", name="documents", methods={"GET","POST"})
* @ParamConverter("page", options={"mapping": {"slug": "slug"}})
*/
public function documents(Page $page, Request $request)
{
$foo = $repo->doSomethingDifferentWithEntities($page)
$bar = $this->transformer->transform($foo);
}