Явная транзакция в doctrine2 с использованием транзакционного метода

#php #doctrine-orm #zend-framework2

#php #doctrine-orm #zend-framework2

Вопрос:

Я пытаюсь реализовать простую обработку форм, используя EntityManager::transactional(function($em) {}); подход. Кажется довольно простым, но возникает вопрос: как я могу передать дополнительные значения такой реализации? Чтобы быть точным, я хочу сделать следующее

 $em  = $this->getServiceLocator()->get('DoctrineORMEntityManager');
$request = $this->getRequest();
$form = new BugForm();
$form->get('reporter')->setValueOptions(
    $em->getRepository('ApplicationEntityPerson')->getPersonListArray()
);
$form->get('engineer')->setValueOptions(
    $em->getRepository('ApplicationEntityPerson')->getPersonListArray()
);
$form->get('products')->setValueOptions(
    $em->getRepository('ApplicationEntityProduct')->getProductListArray()
);
$confirmation = "";

if($request->isPost()) {
    $em->transactional(function($em) {
        $form = new BugForm();
        $request = $this->getRequest();
        $form->setData($request->getPost());
        if($form->isValid()) {
            $form = new BugForm();
            $hydrator = new DoctrineHydrator($em);
            $data = $form->getData();
            $data['created'] = time();
            $data['status'] = 'OPEN';
            $bug = $hydrator->hydrate($data, new Bug());

            $em->persist($bug);
            $em->flush();
            $confirmation = "Created bug with ID ".$bug->getId()."<br/>";
        }
    });
}

return array(
    'form'         => $form,
    'confirmation' => $confirmation
);
 

Проблема в том, что this->getRequest() вызов анонимной функции не создает данные, поэтому я не могу заполнить объект BugForm. Конечно, я мог бы просто использовать _POST там суперглобальный массив, но это не кажется правильным…

Ответ №1:

Для использования $this в анонимной функции вы должны использовать PHP 5.4 или более поздней версии. Вы также можете решить свою проблему, сделав $request из родительской области доступной в области закрытия, используя use языковую конструкцию, например:

 $em->transactional(function($em) use ($request) {
    $form = new BugForm();
    $form->setData($request->getPost());
    if($form->isValid()) {
        $form = new BugForm();
        $hydrator = new DoctrineHydrator($em);
        $data = $form->getData();
        $data['created'] = time();
        $data['status'] = 'OPEN';
        $bug = $hydrator->hydrate($data, new Bug());

        $em->persist($bug);
        $em->flush();
        $confirmation = "Created bug with ID ".$bug->getId()."<br/>";
    }
});
 

Также вы должны знать, что $confirmation переменная в замыкании находится в области, отличной $confirmation от переменной, которую вы возвращаете в родительской функции. Чтобы изменить $confirmation переменную в родительской области, вы должны сделать ее доступной по ссылке в области закрытия:

 $em->transactional(function($em) use ($request, amp;$confirmation) {
 

Комментарии:

1. Я не знал об use этом, но сделал уродливый взлом с настройкой $confirmation на глобальный. В любом случае спасибо 🙂