Décrivez ici votre problème ou ce que vous cherchez à faire.
<?php
namespace App\Serializer\Normalizer;
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
class CourseNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface
{
public function __construct(private ObjectNormalizer $normalizer)
{
}
public function normalize($object, string $format = null, array $context = []): array
{
$data = $this->normalizer->normalize($object, $format, $context);
// TODO: add, edit, or delete some data
return $data;
}
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
return $data instanceof \App\Entity\Course;
}
public function hasCacheableSupportsMethod(): bool
{
return true;
}
}
Ce que je veux
Je veux serializer mes données en JSON
Décrivez ce que vous cherchez à obtenir.
Ce que j'obtiens
App\Serializer\Normalizer\CourseNormalizer::__construct(): Argument #1 ($normalizer) must be of type Symfony\Component\Serializer\Normalizer\ObjectNormalizer, Symfony\Component\Serializer\Debug\TraceableNormalizer given, called in H:\Php\Framework\Symfony\Evaluation\var\cache\dev\ContainerYNqPeoi\getDebug_SerializerService.php on line 85
Décrivez vos éventuelles erreurs ou ce que vous obtenez à la place de ce que vous attendez :(
Oui, tu peux soit préciser le max depth, soit utiliser les groupes pour choisir les champs à sérialiser dans tes entités, l'avantage de cette solution,c'est que tu peux définir les champs que tu vas récupérer sur les entités liées en fonction de ton contexte, l'inconvénient étant que c'est un peu plus verbeux (il faut ajouter les annotations dans les entités).
Par ex :
#[Groups(['course:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['course:read', 'professor:read'])]
private ?string $name = null;
#[ORM\Column(length: 20, nullable: true)]
#[Groups(['course:read'])]
private ?string $alias = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
#[Groups(['course:read'])]
private ?\DateTimeInterface $create_at = null;
et dans le controleur :
return $this->json($course->search($request->query->get('q')), 200, [], ['groups' => ['course:read']]);
De cette façon tu peux afficher les champs que tu souhaites en fonction du groupe appelé.
Il nous faut le code qui utilise ton normalizer pour mieux comprendre.
En tout cas l'erreur est claire : tu passes un objet de type TraceableNormalizer
alors que le constructeur s'attend à un ObjectNormalizer
.
<?php
namespace App\Controller;
use App\Repository\CourseRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* Summary of ApiController
*/
class ApiController extends AbstractController
{
/**
* @param Request $request
* @param CourseRepository $course
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
#[Route('/api/search/course', 'api.course.search')]
public function courseSearch(Request $request, CourseRepository $course)
{
return $this->json($course->search($request->query->get('q')));
}
}
quand j'essaie de récupèrer les données en json sans la serialization
j'ai une erreur
A circular reference has been detected when serializing the object of class "App\Entity\Course" (configured limit: 1).
App\Entity\Course
ressemble à quoi ?
Et tu n'as pas fait voir le code qui utilise le normalizer. C'est dans $course->search()
?
Bonjour,
Il faudrait voir les groupes de sérialisation que tu définis dans tes entités (et entités liées).
Sans voir, je dirais que tu sérialises une relation sur une entité liée et que dans l'entité liée tu fais la même chose vers l'entité Course.
<?php
namespace App\Entity;
use App\Repository\CourseRepository;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: CourseRepository::class)]
class Course
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
#[ORM\Column(length: 20, nullable: true)]
private ?string $alias = null;
#[ORM\Column]
private ?int $pond = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $create_at = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $update_at = null;
#[ORM\ManyToOne(inversedBy: 'courses', cascade:['persist'])]
#[ORM\JoinColumn(nullable: false)]
private ?Professor $professor = null;
#[ORM\ManyToOne(inversedBy: 'courses')]
#[ORM\JoinColumn(nullable: false)]
private ?Level $level = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $description = null;
public function __construct()
{
if (is_null($this->create_at)) {
$this->create_at = new DateTime();
}
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getAlias(): ?string
{
return $this->alias;
}
public function setAlias(?string $alias): self
{
$this->alias = $alias;
return $this;
}
public function getPond(): ?int
{
return $this->pond;
}
public function setPond(int $pond): self
{
$this->pond = $pond;
return $this;
}
public function getCreateAt(): ?\DateTimeInterface
{
return $this->create_at;
}
public function setCreateAt(\DateTimeInterface $create_at): self
{
$this->create_at = $create_at;
return $this;
}
public function getUpdateAt(): ?\DateTimeInterface
{
return $this->update_at;
}
public function setUpdateAt(?\DateTimeInterface $update_at): self
{
$this->update_at = $update_at;
return $this;
}
public function getProfessor(): ?Professor
{
return $this->professor;
}
public function setProfessor(?Professor $professor): self
{
$this->professor = $professor;
return $this;
}
public function __toString()
{
return $this->getName() . ' ' . $this->getLevel();
}
public function getLevel(): ?Level
{
return $this->level;
}
public function setLevel(?Level $level): self
{
$this->level = $level;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $descroption): self
{
$this->description = $descroption;
return $this;
}
}
à ça
Course -> professor -> courses -> Professor
etc
J'ai eu le même problème la semaine dernière et j'ai ajouté
* @MaxDepth(1)
sur les relations et hop.
il fallait installer
composer require symfony/serializer
https://www.novaway.fr/blog/tech/comment-utiliser-le-serializer-symfony