Обработка на въвеждане на Json
Случай на употреба
Представете си даден случай на използване на изпращане на цял JSON чрез формуляр (чрез кодиращ масив във Frontend) като този:
Свързана статия: Работа с Vue.js форма в Symfony
Проблемът
Манипулаторът на формуляри на Symfony позволява използването на различни типове вход като TextType
, ArrayChoiceList
, ChoiceType
и т.н., докато при използване на базиран на Array
тип резултатът е празен масив. Единственият работещ случай е TextType
, но той все още дава само необработен json — но това е нежелан резултат.
JsonType
След като се борих известно време, единственото работещо решение, което намерих, е предоставянето на нов тип въвеждане (JsonType
) и нов DataTransformer
като този:
DataTransformer
<?php namespace App\Form\DataTransformer; use Symfony\Component\Form\DataTransformerInterface; /** * Handles transforming json to array and backward */ class JsonTransformer implements DataTransformerInterface { /** * @inheritDoc */ public function reverseTransform($value): mixed { if (empty($value)) { return []; } return json_decode($value); } /** * @ihneritdoc */ public function transform($value): mixed { if (empty($value)) { return json_encode([]); } return json_encode($value); } }
JsonType
<?php namespace App\Form\Type; use App\Form\DataTransformer\JsonTransformer; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\SerializerInterface; /** * Handles json based input (for example multiselect tag) * Will only transform the json to array (and back), * * If necessary, could probably accept custom options (className) which would be used to * transform the data into given class via {@see SerializerInterface} */ class JsonType extends AbstractType { /** * @inheritDoc */ public function getParent(): string { return TextType::class; } /** * @inheritDoc */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->addModelTransformer(new JsonTransformer()); } }
Резюме
Крайният резултат е масив, трансформиран от json.