【问题标题】:How separate code from controller to Repository & Factory [closed]如何将代码从控制器分离到存储库和工厂 [关闭]
【发布时间】:2021-10-10 10:32:38
【问题描述】:

我正在学习 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();
    }
}

【问题讨论】:

    标签: php symfony factory symfony5


    【解决方案1】:

    Symfony 表单非常适合处理所有类型的底层数据,例如实体、dto-object、数组等。

    这取决于您的用例和业务逻辑以及您(或您的团队)的决定

    在您的情况下,您可以使用 $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()
        ]);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      相关资源
      最近更新 更多