Сериализация загруженного файла не допускается
Я пытаюсь загрузить файл через пакет vichuploader на моем объекте Users. Используя hwioauthbundle, который реализует UserInterface, и я думаю, что ошибки происходят из этого пакета... Поэтому каждый раз, когда я пытаюсь загрузить файл, я получаю это исключение:
Сериализация Symfony\Component\HttpFoundation\File\UploadedFile не допускается
Я уже пробовал это решение, но и то же исключение.
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass;
use Symfony\Component\Security\Core\User\UserInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser;
/**
* Users
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="AppBundle\Repository\UsersRepository")
*
*/
class Users extends OAuthUser
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="first_name", type="string", length=255)
*/
private $firstName;
/**
* @var string
*
* @ORM\Column(name="last_name", type="string", length=255)
*/
private $lastName;
/**
* @var string
*
* @ORM\Column(name="civility", type="string", length=255, nullable=true)
*/
private $civility;
/**
* @var string
*
* @ORM\Column(name="avatar", type="string", length=255, nullable=true)
*/
private $avatar;
/**
* @var string
*
* @ORM\Column(name="qualification", type="string", length=255, nullable=true)
*/
private $qualification;
/**
* @var string
*
* @ORM\Column(name="level", type="string", length=255, nullable=true)
*/
private $level;
/**
* @var \DateTime
*
* @ORM\Column(name="birth_date", type="date", nullable=true)
*/
private $birthDate;
/**
* @var \DateTime
*
* @ORM\Column(name="hiring_date", type="date", nullable=true)
*/
private $hiringDate;
/**
* @var string
*
* @ORM\Column(name="country", type="string", length=255, nullable=true)
*/
private $country;
/**
* @var string
*
* @ORM\Column(name="city", type="string", length=255, nullable=true)
*/
private $city;
/**
* @var string
*
* @ORM\Column(name="linkedin_profil", type="string", length=255, nullable=true)
*/
private $linkedinProfil;
/**
* @var string
*
* @ORM\Column(name="web_site", type="string", length=255, nullable=true)
*/
private $webSite;
/**
* @var \DateTime
*
* @ORM\Column(name="date_last_cnx", type="datetimetz", nullable=true)
*/
private $dateLastCnx;
/**
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Files",cascade={"persist"})
* @ORM\JoinColumn(name="file_id", referencedColumnName="id")
*/
public $cv;
/** @ORM\Column(name="google_id", type="string", length=255, nullable=true) */
private $google_id;
Files.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* Files
* @Vich\Uploadable
* @ORM\Table(name="files")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FilesRepository")
*/
class Files
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName", size="imageSize")
*
* @var File
*/
protected $imageFile;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
protected $imageName;
public function getId()
{
return $this->id;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* @return Product
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
/**
* @return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @param string $imageName
*
* @return Product
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* @return string|null
*/
public function getImageName()
{
return $this->imageName;
}
}
Моя форма Userstype:
use AppBundle\Form\FilesType;
->add('cv',FilesType::class)
Моя форма Filestype:
-> add('imageFile',
VichFileType::class, [
'required' => false,
'allow_delete' => true,
'download_link' => true,
'label' => false,
]);
3 ответа
Вы сериализуете ImageFile
сущность в этом коде, поэтому вы получаете ошибку, попробуйте удалить ее и добавить updatedAt
поле, чтобы доктрина могла отслеживать изменения на объекте:
/**
* Files
* @ORM\Table(name="files")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FilesRepository")
* @Vich\Uploadable
*/
class Files implements \Serializable
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName", size="imageSize")
*
* @var File
*/
protected $imageFile;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
protected $imageName;
/**
* @ORM\Column(type="datetime")
*
* @var string
*/
protected $updatedAt;
public function getId()
{
return $this->id;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* @return Product
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
/**
* @return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @param string $imageName
*
* @return Product
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* @return string|null
*/
public function getImageName()
{
return $this->imageName;
}
/** @see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->imageName,
));
}
/** @see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
/**
* @return string
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* @param string $updatedAt
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
}
}
Проверьте это, у одного из ваших отношений пользователей есть свойство UploadedFile, которое по сути является файлом, также известным как файловый поток, который не может быть сериализован. Поэтому вам нужно указать, что вы хотите сериализовать:
https://symfony.com/doc/3.3/security/entity_provider.html
В основном вам нужно только сериализованный идентификатор, имя пользователя и пароль (три - это пример кода на приведенной выше странице)
Для Symfony5
Class User implement UserInterface
public function __serialize(): array
{
return [
'id' => $this->id,
'email' => $this->email,
//......
];
}
public function __unserialize(array $serialized): User
{
$this->id = $serialized['id'];
$this->email = $serialized['email'];
// .....
return $this;
}