Как получить доступ к сервисам или конфигурации изнутри формы¶
Иногда вам может понадобиться получить доступ к сервису или другой конфигурации изнутри вашего класса формы. Чтобы сделать это, у вас есть 2 варианта:
1) Передать опции в вашу форму¶
Наиболее простой способ передать сервисы или конфигурацию в вашу форму - через
опции форм. Представьте, что вам нужно получить доступ к менеджеру сущностей
Doctrine, чтобы вы могли сделать запрос. Для начала, позвольте (на самом деле,
потребуйте), чтобы новая опция entity_manager
была передана в вашу форму:
// src/Form/TaskType.php
// ...
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
// ...
$resolver->setRequired('entity_manager');
}
}
Теперь, когда вы сделала это, вы должны передать опцию entity_manager
при
создании вашей формы:
// src/Controller/DefaultController.php
use App\Form\TaskType;
// ...
public function new()
{
$em = $this->getDoctrine()->getManager();
$task = ...;
$form = $this->createForm(TaskType::class, $task, array(
'entity_manager' => $em,
));
// ...
}
Наконец, опция entity_manager
доступна в аргументе $options
вашего метода
buildForm()
:
// src/Form/TaskType.php
// ...
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** @var \Doctrine\ORM\EntityManager $em */
$em = $options['entity_manager'];
// ...
}
// ...
}
Используйте этот метод, чтобы передать что угодно в вашу форму.
2) Определить вашу форму, как сервис¶
В качестве альтернативы, вы можете определить ваш класс формы, как сервис. Это хорошая идея, если вы хотите использовать форму повторно в нескольких местах - регистрация формы в качестве сервиса облегчает это.
Представьте, что вам нужно получить доступ к объекту EntityManager, чтобы вы могли сделать запрос. Для начала, добавьте это в качестве аргумента к вашему классу формы:
// src/Form/TaskType.php
use Doctrine\ORM\EntityManagerInterface;
// ...
class TaskType extends AbstractType
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
// ...
}
Если вы используете автомонтирование и
автоконфигурацию, то вам больше ничего не нужно
делать. Symfony автоматически передаст правильный объект EntityManager
в ваш
метод __construct()
.
Если вы не используете автомонтирование и автоконфигурацию, зарегистрируйте вашу
форму, как сервис, вручную и тегируйте с помощью form.type
:
- YAML
1 2 3 4 5
# config/services.yaml services: App\Form\TaskType: arguments: ['@doctrine.orm.entity_manager'] tags: [form.type]
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<!-- config/services.xml --> <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="App\Form\TaskType"> <argument type="service" id="doctrine.orm.entity_manager"/> <tag name="form.type" /> </service> </services> </container>
- PHP
1 2 3 4 5 6 7 8
// config/services.php use App\Form\TaskType; use Symfony\Component\DependencyInjection\Reference; $container->register(TaskType::class) ->addArgument(new Reference('doctrine.orm.entity_manager')) ->addTag('form.type') ;
Вот и всё! Ваш контроллер - где вы создали форму - не требует никаких изменений:
Symfony достаточно умна, чтобы загружать TaskType
из контейнера.
Смотрите form-field-service, чтобы получить больше информации.
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.