У меня большие проблемы с сериализацией коллекции, из которой я удалил первый элемент.
У меня есть объект CompaniesCollection с отношением Many2Many к объекту Company.
/**
* @ORM\ManyToMany(targetEntity = "App\Entity\Company")
* @Groups({"get-by-collection-owner"})
*/
private $items;
Когда я извлекаю объект из этой коллекции, я получаю элементы в виде массива из двух элементов, которые я добавил в первую очередь. я сериализую это
{
"id": 19,
"name": "collection dummy name",
"items": [
{
"id": 431,
"name": "Company 1"
},
{
"id": 435,
"name": "Company 2"
}
],
"createdAt": "2019-03-11T13:55:43+01:00",
"updatedAt": "2019-03-11T15:48:57+01:00"
},
Затем я удаляю ПЕРВЫЙ элемент:
$collection->removeItem($companyToRemove);
$em = $this->getDoctrine()->getManager();
$em->persist($collection);
$em->persist($companyToRemove);
$em->flush();
$results = $companiesCollectionRepository->getCollections($companyLoader->getCurrentCompany());
Сериализуем $results и получаем не массив из одного элемента, а объект с ключом второго элемента из предыдущего массива элементов:
{
"id": 19,
"name": "collection dummy name",
"items": {
"1": {
"id": 435,
"name": "Company 2"
}
},
"createdAt": "2019-03-11T13:55:43+01:00",
"updatedAt": "2019-03-11T15:52:48+01:00"
},
Когда я перезагружаю страницу и получаю этот объект, коллекция снова представляет собой массив из одного элемента, а не объект. Очевидно, что Doctrine не получает новых результатов из базы данных, а возвращает уже загруженные в память данные.
И сериализатор, скорее всего, рассматривает этот «массив» как «объект», потому что он начинается не с 0 для ключа первого элемента массива, а с ключа 1.
Есть ли способ сделать этот запрос снова, чтобы я получил свежесгенерированные ключи или обновил эти ключи?
Обновлено:
На самом деле я наконец нашел простое решение для этого: обновить после сброса
$collection->removeItem($companyToRemove);
$em = $this->getDoctrine()->getManager();
$em->persist($collection);
$em->persist($companyToRemove);
$em->flush();
$em->refresh($collection);






Я столкнулся с той же проблемой. И вот еще одно решение, которое, кажется, работает для меня.
Пользовательский нормализатор, который будет использоваться для коллекций с «дырками» в ключах:
namespace App\Serializer\Normalizer;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerAwareTrait;
class DoctrineCollectionNormalizer implements NormalizerInterface, SerializerAwareInterface
{
use SerializerAwareTrait;
public function normalize($object, $format = null, array $context = array()): array
{
/* @var $object Collection */
$values = $object->getValues();
$object->clear();
foreach ($values as $k => $value) {
$object->set($k, $value);
}
return $this->serializer->normalize($object, $format, $context);
}
public function supportsNormalization($data, $format = null): bool
{
if ($data instanceof Collection) {
$keys = $data->getKeys();
$count = count($keys);
$lastKey = (int) array_pop($keys);
return $count && $lastKey !== $count-1;
}
return false;
}
}
Сегодня я столкнулся с той же проблемой. Спасибо @storm за пример кода. Пока нет лучшего решения, я буду использовать это