这听起来有点复杂,因为我对JSON完全陌生,但是请允许我,我真的很需要这个。 让我开始展示我的实体
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\TypeParkingRepository")
*/
class TypeParking
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=55)
*/
private $libelle;
/**
* @ORM\Column(type="date", nullable=true)
*/
private $jourdebut;
/**
* @ORM\Column(type="date", nullable=true)
*/
private $jourfin;
/**
* @ORM\Column(type="json_array", nullable=true)
*/
private $exception;
public function getId(): ?int
{
return $this->id;
}
public function getJourdebut(): ?\DateTimeInterface
{
return $this->jourdebut;
}
public function setJourdebut(\DateTimeInterface $jourdebut): self
{
$this->jourdebut = $jourdebut;
return $this;
}
public function getJourfin(): ?\DateTimeInterface
{
return $this->jourfin;
}
public function setJourfin(\DateTimeInterface $jourfin): self
{
$this->jourfin = $jourfin;
return $this;
}
public function getException() {
return array_merge([
'name' => null,
'datedebut' => null,
'datefin' => null,
'heuredebut' => null,
'heurefin' => null,
// other sub-fields "empty" values
], $this->exception ?? [] // prevent array_merge from failing if exception is empty
);
}
public function setException($exception): self
{
$this->exception = $exception;
return $this;
}
public function getLibelle(): ?string
{
return $this->libelle;
}
public function setLibelle(string $libelle): self
{
$this->libelle = $libelle;
return $this;
}
}
您可以看到我有一个称为异常的属性,现在该属性具有许多子属性,例如名称,datedebut,datefin ... 因此,我必须使用JSON格式。 所以我创建了一个名为TypeParkingType.php的表单类型。
<?php
namespace App\Form;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use App\Entity\TypeParking;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TypeParkingType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('libelle')
->add('tempsmax')
->add('jourdebut')
->add('jourfin')
->add('jourstravail_jour', TextType::class, ['property_path' => 'jourstravail[jour]'])
->add('jourstravail_debut', TextType::class, ['property_path' => 'jourstravail[debut]'])
->add('jourstravail_fin', TextType::class, ['property_path' => 'jourstravail[fin]'])
->add('Exception_Name', TextType::class, ['property_path' => 'exception[name]'])
->add('Starting_date', DateTimeType::class, [
'property_path' => 'exception[datedebut]',
])
->add('Ending_date', DateTimeType::class, [
'property_path' => 'exception[datefin]',
])
->add('Starting_time', TextType::class, ['property_path' => 'exception[heuredebut]'])
->add('Ending_time', TextType::class, ['property_path' => 'exception[heurefin]'])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => TypeParking::class,
]);
}
}
可悲的是,这是行不通的,因为即使将数据插入数据库后,它仍会以一种无法读取的不切实际的方式进行操作。 为了使其更加复杂,每种形式都可以具有多个异常,这意味着我必须以如下方式解析数据:例如:{exceptionName(datedebut:...,datefin ...,time:...), exceptionname2 ....}
我的意思是不可能做到的是,它给了我一个像这样的字符串https://imgur.com/a/ydYbpaQ,它是:
当我进入所选类型的编辑页面时,出现此错误:
Unable to transform value for property path "exception[datedebut]": Expected a \DateTimeInterface.
我无法从中一一提取数据
TL; DR:如何将与异常相关的值插入数据库中的单个JSON字符串中。
答案 0 :(得分:0)
我的建议是添加一个新的ExceptionType
,将异常字段移至其中(给定data_class
中的null
(本质上是一个数组)。
以您的主要形式:
->add('exception', CollectionType::class, [
'entry_type' => ExceptionType::class,
// have a look at the other options!
]);
(有关CollectionType
的信息,请参见https://symfony.com/doc/current/reference/forms/types/collection.html)
对于您的序列化和反序列化问题(本质上就是这样),我建议您使用数据转换器,将其应用于日期字段。
它实际上需要一个日期字符串'2019-01-02'或任何东西,并将其转换为DateTime,反之亦然。这样,您的表单提供的DateTime不会序列化为某个对象,而是一个字符串。
请参阅https://symfony.com/doc/current/form/data_transformers.html
您的CallbackTransformer类似于:
new CallbackTransformer(
function (string $string=null) {
// transform string to DateTime
return $string ? new \DateTime($string) : null;
},
function (\DateTime $datetime=null) {
// transform the string back to an array
return $datetime ? $datetime->format('Y-m-d') : null
}
)
为了使它对于您现有的数据库条目而言正常工作,必须删除它们或手动修复,以便日期字符串仅为YYYY-MM-DD而不是{ ... }
,并且必须包装异常,以便远在[[...]'中,因此它是一个数组。
更新:
当然,由于对异常的更改(现在包含多个异常,而不是一个),您必须更改Entity的getException方法:
public function getException() {
return $this->exception ?? [];
}
可能您可以删除整个方法...我不确定tbh。