如何将代码从控制器分离到存储库和工厂
How separate code from controller to Repository & Factory
我正在学习 symfony 5。我有一个控制器,但我想将逻辑分解为一个工厂和一个存储库。我在使用 FormBuilder 时遇到了一个小问题。如果工厂中没有 Formbuilder,它会传递 Request,在本例中是通过 Form。
这个解决方案确实适用于 Form,但我做对了吗?
TestFactory.php 请求
class TestFactory
{
public function create(Request $request)
{
$test = new Test();
$test->setTest1($request->get('test1');
$test->setTest2($request->get('test2');
return $test;
}
}
TestController.php
class TestController extends AbstractController
{
public function test(Request $request, TestFactory $factory, TestRepository $repository):Response
{
$form = $this->createForm(TestType::class);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$test = $factory->create($form);
$repository->save($test);
}
return $this->render('test.html.twig', [
'form' => $form->createView()
]);
}
}
TestFactory.php
class TestFactory
{
public function create(Form $form)
{
$test = new Test();
$test->setTest1($form->get('test1')->getData());
$test->setTest2($form->get('test2')->getData());
return $test;
}
}
TestRepository.php
class TestRepository extends ServiceEntityRepository
{
private $entityManager;
public function __construct(ManagerRegistry $registry, EntityManagerInterface $entityManager)
{
parent::__construct($registry, Test::class);
$this->entityManager = $entityManager;
}
public function save(Test $test)
{
$this->entityManager->persist($test);
$this->entityManager->flush();
}
}
Symfony 表单非常适合处理所有类型的基础数据,例如实体、dto 对象、数组等。
这取决于您的用例和业务逻辑以及您(或您的团队)的决定
在您的情况下,您可以使用 $form->getData()
并进一步传递其值...
最常见的方法是将您的 FormType 直接绑定到特定实体。
让我们坚持将 TestType
作为表单,将 Test
作为生活在 src/Entity/Test.php
中的实体
在 TestType.php 你有 configureOptions
方法
public function buildForm(FormBuilderInterface $builder, array $options){
// Assuming you have a property named $nickname in your Test class
$builder->add('nickname');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Test::class, // this tells your form to bind form-fields to a specific entity
'empty_data' => new Test(), // crete new instance, if no data was passed
]);
}
在你的控制器中
public function test(Request $request, TestFactory $factory, TestRepository $repository):Response
{
$form = $this->createForm(TestType::class); // since you dont pass object of Test as a 2nd param, form will automagicaly create new instance for you.
$form->handleRequest($request);
// don't forget to check for validation errors
if ($form->isSubmitted() && $form->isValid()) {
$test = $form->getData(); // hier you'll get an instance of Test with all user input already set
// so now you only have to save it to the database
$repository->save($test);
// do set succesefull flash-message ...
// redirect to ...
}
return $this->render('test.html.twig', [
'form' => $form->createView()
]);
}
我正在学习 symfony 5。我有一个控制器,但我想将逻辑分解为一个工厂和一个存储库。我在使用 FormBuilder 时遇到了一个小问题。如果工厂中没有 Formbuilder,它会传递 Request,在本例中是通过 Form。 这个解决方案确实适用于 Form,但我做对了吗?
TestFactory.php 请求
class TestFactory
{
public function create(Request $request)
{
$test = new Test();
$test->setTest1($request->get('test1');
$test->setTest2($request->get('test2');
return $test;
}
}
TestController.php
class TestController extends AbstractController
{
public function test(Request $request, TestFactory $factory, TestRepository $repository):Response
{
$form = $this->createForm(TestType::class);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$test = $factory->create($form);
$repository->save($test);
}
return $this->render('test.html.twig', [
'form' => $form->createView()
]);
}
}
TestFactory.php
class TestFactory
{
public function create(Form $form)
{
$test = new Test();
$test->setTest1($form->get('test1')->getData());
$test->setTest2($form->get('test2')->getData());
return $test;
}
}
TestRepository.php
class TestRepository extends ServiceEntityRepository
{
private $entityManager;
public function __construct(ManagerRegistry $registry, EntityManagerInterface $entityManager)
{
parent::__construct($registry, Test::class);
$this->entityManager = $entityManager;
}
public function save(Test $test)
{
$this->entityManager->persist($test);
$this->entityManager->flush();
}
}
Symfony 表单非常适合处理所有类型的基础数据,例如实体、dto 对象、数组等。
这取决于您的用例和业务逻辑以及您(或您的团队)的决定
在您的情况下,您可以使用 $form->getData()
并进一步传递其值...
最常见的方法是将您的 FormType 直接绑定到特定实体。
让我们坚持将 TestType
作为表单,将 Test
作为生活在 src/Entity/Test.php
在 TestType.php 你有 configureOptions
方法
public function buildForm(FormBuilderInterface $builder, array $options){
// Assuming you have a property named $nickname in your Test class
$builder->add('nickname');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Test::class, // this tells your form to bind form-fields to a specific entity
'empty_data' => new Test(), // crete new instance, if no data was passed
]);
}
在你的控制器中
public function test(Request $request, TestFactory $factory, TestRepository $repository):Response
{
$form = $this->createForm(TestType::class); // since you dont pass object of Test as a 2nd param, form will automagicaly create new instance for you.
$form->handleRequest($request);
// don't forget to check for validation errors
if ($form->isSubmitted() && $form->isValid()) {
$test = $form->getData(); // hier you'll get an instance of Test with all user input already set
// so now you only have to save it to the database
$repository->save($test);
// do set succesefull flash-message ...
// redirect to ...
}
return $this->render('test.html.twig', [
'form' => $form->createView()
]);
}