Как уменьшить дублирование кода с помощью "inherit_data"
Дата обновления перевода 2025-08-25
Как уменьшить дублирование кода с помощью "inherit_data"
Опция поля формы inherit_data может быть очень полезной, когда у вас есть
некоторые дублированные поля в разных сущностях. Например, представьте, что у
вас есть две сущности: Company и Customer:
1 2 3 4 5 6 7 8 9 10 11 12 13
// src/Entity/Company.php
namespace App\Entity;
class Company
{
    private string $name;
    private string $website;
    private string $address;
    private string $zipcode;
    private string $city;
    private string $country;
}1 2 3 4 5 6 7 8 9 10 11 12 13
// src/Entity/Customer.php
namespace App\Entity;
class Customer
{
    private string $firstName;
    private string $lastName;
    private string  $address;
    private string $zipcode;
    private string $city;
    private string $country;
}Как вы можете увидеть, каждая сущность имеет несколько одинаковых полей: address,
zipcode, city, country.
Начните с построения двух форм для этих сущностей, CompanyType и CustomerType:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Form/Type/CompanyType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class CompanyType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', TextType::class)
            ->add('website', TextType::class);
    }
}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Form/Type/CustomerType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class CustomerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('firstName', TextType::class)
            ->add('lastName', TextType::class);
    }
}Вместо того, чтобы включать дублированные поля address, zipcode, city
и country в обе эти формы, создайте третью форму под названием LocationType:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// src/Form/Type/LocationType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class LocationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('address', TextareaType::class)
            ->add('zipcode', TextType::class)
            ->add('city', TextType::class)
            ->add('country', TextType::class);
    }
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'inherit_data' => true,
        ]);
    }
}Форма локации имеет интересную установленную опцию, под названием inherit_data.
Эта опция позволяет форме наследовать данные из родительской формы. Если её встроить
в форму компании, поля формы локации будут иметь доступ к свойствам экземпляра
Company. Если её встроить в форму клиента, тогда поля будут иметь доступ к
свойствам экземпляра Customer. Легко, правда же?
Note
Вместо того, чтобы устанавливать опцию inherit_data внутри LocationType,
вы также можете (как и с любой другой опцией) передать её в третьем аргументе
$builder->add().
Наконец, закончите работе, добавив форму локации в две ваши первоначальные формы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Form/Type/CompanyType.php
namespace App\Form\Type;
use App\Entity\Company;
use Symfony\Component\Form\AbstractType;
// ...
class CompanyType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        // ...
        $builder->add('foo', LocationType::class, [
            'data_class' => Company::class,
        ]);
    }
}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Form/Type/CustomerType.php
namespace App\Form\Type;
use App\Entity\Customer;
use Symfony\Component\Form\AbstractType;
class CustomerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        // ...
        $builder->add('bar', LocationType::class, [
            'data_class' => Customer::class,
        ]);
    }
}Вот и всё! Вы извлекли дублированные определения полей в отдельную форму локации, которую вы можете использовать повторно, когда вам это понадобится.
Warning
Формы с установленной опцией inherit_data не могут иметь слушателей
событий *_SET_DATA.